1/* $OpenBSD: mta_session.c,v 1.151 2024/01/20 09:01:03 claudio Exp $ */ 2 3/* 4 * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> 5 * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org> 6 * Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net> 7 * Copyright (c) 2012 Eric Faurot <eric@openbsd.org> 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22#include <sys/stat.h> 23 24#include <ctype.h> 25#include <errno.h> 26#include <inttypes.h> 27#include <stdlib.h> 28#include <string.h> 29#include <time.h> 30#include <tls.h> 31#include <unistd.h> 32 33#include "smtpd.h" 34#include "log.h" 35 36#define MAX_TRYBEFOREDISABLE 10 37 38#define MTA_HIWAT 65535 39 40enum mta_state { 41 MTA_INIT, 42 MTA_BANNER, 43 MTA_EHLO, 44 MTA_HELO, 45 MTA_LHLO, 46 MTA_STARTTLS, 47 MTA_AUTH, 48 MTA_AUTH_PLAIN, 49 MTA_AUTH_LOGIN, 50 MTA_AUTH_LOGIN_USER, 51 MTA_AUTH_LOGIN_PASS, 52 MTA_READY, 53 MTA_MAIL, 54 MTA_RCPT, 55 MTA_DATA, 56 MTA_BODY, 57 MTA_EOM, 58 MTA_LMTP_EOM, 59 MTA_RSET, 60 MTA_QUIT, 61}; 62 63#define MTA_FORCE_ANYSSL 0x0001 64#define MTA_FORCE_SMTPS 0x0002 65#define MTA_FORCE_TLS 0x0004 66#define MTA_FORCE_PLAIN 0x0008 67#define MTA_WANT_SECURE 0x0010 68#define MTA_DOWNGRADE_PLAIN 0x0080 69 70#define MTA_TLS 0x0100 71#define MTA_TLS_VERIFIED 0x0200 72 73#define MTA_FREE 0x0400 74#define MTA_LMTP 0x0800 75#define MTA_WAIT 0x1000 76#define MTA_HANGON 0x2000 77#define MTA_RECONN 0x4000 78 79#define MTA_EXT_STARTTLS 0x01 80#define MTA_EXT_PIPELINING 0x02 81#define MTA_EXT_AUTH 0x04 82#define MTA_EXT_AUTH_PLAIN 0x08 83#define MTA_EXT_AUTH_LOGIN 0x10 84#define MTA_EXT_SIZE 0x20 85 86struct mta_session { 87 uint64_t id; 88 struct mta_relay *relay; 89 struct mta_route *route; 90 char *helo; 91 char *mxname; 92 93 char *username; 94 95 int flags; 96 97 int attempt; 98 int use_smtps; 99 int use_starttls; 100 int use_smtp_tls; 101 int ready; 102 103 struct event ev; 104 struct io *io; 105 int ext; 106 107 size_t ext_size; 108 109 size_t msgtried; 110 size_t msgcount; 111 size_t rcptcount; 112 int hangon; 113 114 enum mta_state state; 115 struct mta_task *task; 116 struct mta_envelope *currevp; 117 FILE *datafp; 118 size_t datalen; 119 120 size_t failures; 121 122 char replybuf[2048]; 123}; 124 125static void mta_session_init(void); 126static void mta_start(int fd, short ev, void *arg); 127static void mta_io(struct io *, int, void *); 128static void mta_free(struct mta_session *); 129static void mta_getnameinfo_cb(void *, int, const char *, const char *); 130static void mta_on_ptr(void *, void *, void *); 131static void mta_on_timeout(struct runq *, void *); 132static void mta_connect(struct mta_session *); 133static void mta_enter_state(struct mta_session *, int); 134static void mta_flush_task(struct mta_session *, int, const char *, size_t, int); 135static void mta_error(struct mta_session *, const char *, ...) 136 __attribute__((__format__ (printf, 2, 3))); 137static void mta_send(struct mta_session *, char *, ...) 138 __attribute__((__format__ (printf, 2, 3))); 139static ssize_t mta_queue_data(struct mta_session *); 140static void mta_response(struct mta_session *, char *); 141static const char * mta_strstate(int); 142static void mta_tls_init(struct mta_session *); 143static void mta_tls_started(struct mta_session *); 144static struct mta_session *mta_tree_pop(struct tree *, uint64_t); 145static const char * dsn_strret(enum dsn_ret); 146static const char * dsn_strnotify(uint8_t); 147 148void mta_hoststat_update(const char *, const char *); 149void mta_hoststat_reschedule(const char *); 150void mta_hoststat_cache(const char *, uint64_t); 151void mta_hoststat_uncache(const char *, uint64_t); 152 153 154static void mta_filter_begin(struct mta_session *); 155static void mta_filter_end(struct mta_session *); 156static void mta_connected(struct mta_session *); 157static void mta_disconnected(struct mta_session *); 158 159static void mta_report_link_connect(struct mta_session *, const char *, int, 160 const struct sockaddr_storage *, 161 const struct sockaddr_storage *); 162static void mta_report_link_greeting(struct mta_session *, const char *); 163static void mta_report_link_identify(struct mta_session *, const char *, const char *); 164static void mta_report_link_tls(struct mta_session *, const char *); 165static void mta_report_link_disconnect(struct mta_session *); 166static void mta_report_link_auth(struct mta_session *, const char *, const char *); 167static void mta_report_tx_reset(struct mta_session *, uint32_t); 168static void mta_report_tx_begin(struct mta_session *, uint32_t); 169static void mta_report_tx_mail(struct mta_session *, uint32_t, const char *, int); 170static void mta_report_tx_rcpt(struct mta_session *, uint32_t, const char *, int); 171static void mta_report_tx_envelope(struct mta_session *, uint32_t, uint64_t); 172static void mta_report_tx_data(struct mta_session *, uint32_t, int); 173static void mta_report_tx_commit(struct mta_session *, uint32_t, size_t); 174static void mta_report_tx_rollback(struct mta_session *, uint32_t); 175static void mta_report_protocol_client(struct mta_session *, const char *); 176static void mta_report_protocol_server(struct mta_session *, const char *); 177#if 0 178static void mta_report_filter_response(struct mta_session *, int, int, const char *); 179#endif 180static void mta_report_timeout(struct mta_session *); 181 182 183static struct tree wait_helo; 184static struct tree wait_ptr; 185static struct tree wait_fd; 186static struct tree wait_tls_init; 187static struct tree wait_tls_verify; 188 189static struct runq *hangon; 190 191#define SESSION_FILTERED(s) \ 192 ((s)->relay->dispatcher->u.remote.filtername) 193 194static void 195mta_session_init(void) 196{ 197 static int init = 0; 198 199 if (!init) { 200 tree_init(&wait_helo); 201 tree_init(&wait_ptr); 202 tree_init(&wait_fd); 203 tree_init(&wait_tls_init); 204 tree_init(&wait_tls_verify); 205 runq_init(&hangon, mta_on_timeout); 206 init = 1; 207 } 208} 209 210void 211mta_session(struct mta_relay *relay, struct mta_route *route, const char *mxname) 212{ 213 struct mta_session *s; 214 struct timeval tv; 215 216 mta_session_init(); 217 218 s = xcalloc(1, sizeof *s); 219 s->id = generate_uid(); 220 s->relay = relay; 221 s->route = route; 222 s->mxname = xstrdup(mxname); 223 224 mta_filter_begin(s); 225 226 if (relay->flags & RELAY_LMTP) 227 s->flags |= MTA_LMTP; 228 switch (relay->tls) { 229 case RELAY_TLS_SMTPS: 230 s->flags |= MTA_FORCE_SMTPS; 231 s->flags |= MTA_WANT_SECURE; 232 break; 233 case RELAY_TLS_STARTTLS: 234 s->flags |= MTA_FORCE_TLS; 235 s->flags |= MTA_WANT_SECURE; 236 break; 237 case RELAY_TLS_OPPORTUNISTIC: 238 /* do not force anything, try tls then smtp */ 239 break; 240 case RELAY_TLS_NO: 241 s->flags |= MTA_FORCE_PLAIN; 242 break; 243 default: 244 fatalx("bad value for relay->tls: %d", relay->tls); 245 } 246 247 log_debug("debug: mta: %p: spawned for relay %s", s, 248 mta_relay_to_text(relay)); 249 stat_increment("mta.session", 1); 250 251 if (route->dst->ptrname || route->dst->lastptrquery) { 252 /* We want to delay the connection since to always notify 253 * the relay asynchronously. 254 */ 255 tv.tv_sec = 0; 256 tv.tv_usec = 0; 257 evtimer_set(&s->ev, mta_start, s); 258 evtimer_add(&s->ev, &tv); 259 } else if (waitq_wait(&route->dst->ptrname, mta_on_ptr, s)) { 260 resolver_getnameinfo(s->route->dst->sa, NI_NUMERICSERV, 261 mta_getnameinfo_cb, s); 262 } 263} 264 265void 266mta_session_imsg(struct mproc *p, struct imsg *imsg) 267{ 268 struct mta_session *s; 269 struct msg m; 270 uint64_t reqid; 271 const char *name; 272 int status, fd; 273 struct stat sb; 274 275 switch (imsg->hdr.type) { 276 277 case IMSG_MTA_OPEN_MESSAGE: 278 m_msg(&m, imsg); 279 m_get_id(&m, &reqid); 280 m_end(&m); 281 282 fd = imsg_get_fd(imsg); 283 s = mta_tree_pop(&wait_fd, reqid); 284 if (s == NULL) { 285 if (fd != -1) 286 close(fd); 287 return; 288 } 289 290 if (fd == -1) { 291 log_debug("debug: mta: failed to obtain msg fd"); 292 mta_flush_task(s, IMSG_MTA_DELIVERY_TEMPFAIL, 293 "Could not get message fd", 0, 0); 294 mta_enter_state(s, MTA_READY); 295 return; 296 } 297 298 if ((s->ext & MTA_EXT_SIZE) && s->ext_size != 0) { 299 if (fstat(fd, &sb) == -1) { 300 log_debug("debug: mta: failed to stat msg fd"); 301 mta_flush_task(s, IMSG_MTA_DELIVERY_TEMPFAIL, 302 "Could not stat message fd", 0, 0); 303 mta_enter_state(s, MTA_READY); 304 close(fd); 305 return; 306 } 307 if (sb.st_size > (off_t)s->ext_size) { 308 log_debug("debug: mta: message too large for peer"); 309 mta_flush_task(s, IMSG_MTA_DELIVERY_PERMFAIL, 310 "message too large for peer", 0, 0); 311 mta_enter_state(s, MTA_READY); 312 close(fd); 313 return; 314 } 315 } 316 317 s->datafp = fdopen(fd, "r"); 318 if (s->datafp == NULL) 319 fatal("mta: fdopen"); 320 321 mta_enter_state(s, MTA_MAIL); 322 return; 323 324 case IMSG_MTA_LOOKUP_HELO: 325 m_msg(&m, imsg); 326 m_get_id(&m, &reqid); 327 m_get_int(&m, &status); 328 if (status == LKA_OK) 329 m_get_string(&m, &name); 330 m_end(&m); 331 332 s = mta_tree_pop(&wait_helo, reqid); 333 if (s == NULL) 334 return; 335 336 if (status == LKA_OK) { 337 s->helo = xstrdup(name); 338 mta_connect(s); 339 } else { 340 mta_source_error(s->relay, s->route, 341 "Failed to retrieve helo string"); 342 mta_free(s); 343 } 344 return; 345 346 default: 347 fatalx("mta_session_imsg: unexpected %s imsg", 348 imsg_to_str(imsg->hdr.type)); 349 } 350} 351 352static struct mta_session * 353mta_tree_pop(struct tree *wait, uint64_t reqid) 354{ 355 struct mta_session *s; 356 357 s = tree_xpop(wait, reqid); 358 if (s->flags & MTA_FREE) { 359 log_debug("debug: mta: %p: zombie session", s); 360 mta_free(s); 361 return (NULL); 362 } 363 s->flags &= ~MTA_WAIT; 364 365 return (s); 366} 367 368static void 369mta_free(struct mta_session *s) 370{ 371 struct mta_relay *relay; 372 struct mta_route *route; 373 374 log_debug("debug: mta: %p: session done", s); 375 376 mta_disconnected(s); 377 378 if (s->ready) 379 s->relay->nconn_ready -= 1; 380 381 if (s->flags & MTA_HANGON) { 382 log_debug("debug: mta: %p: cancelling hangon timer", s); 383 runq_cancel(hangon, s); 384 } 385 386 if (s->io) 387 io_free(s->io); 388 389 if (s->task) 390 fatalx("current task should have been deleted already"); 391 if (s->datafp) { 392 fclose(s->datafp); 393 s->datalen = 0; 394 } 395 free(s->helo); 396 397 relay = s->relay; 398 route = s->route; 399 free(s->username); 400 free(s->mxname); 401 free(s); 402 stat_decrement("mta.session", 1); 403 mta_route_collect(relay, route); 404} 405 406static void 407mta_getnameinfo_cb(void *arg, int gaierrno, const char *host, const char *serv) 408{ 409 struct mta_session *s = arg; 410 struct mta_host *h; 411 412 h = s->route->dst; 413 h->lastptrquery = time(NULL); 414 if (host) 415 h->ptrname = xstrdup(host); 416 waitq_run(&h->ptrname, h->ptrname); 417} 418 419static void 420mta_on_timeout(struct runq *runq, void *arg) 421{ 422 struct mta_session *s = arg; 423 424 log_debug("mta: timeout for session hangon"); 425 426 s->flags &= ~MTA_HANGON; 427 s->hangon++; 428 429 mta_enter_state(s, MTA_READY); 430} 431 432static void 433mta_on_ptr(void *tag, void *arg, void *data) 434{ 435 struct mta_session *s = arg; 436 437 mta_connect(s); 438} 439 440static void 441mta_start(int fd, short ev, void *arg) 442{ 443 struct mta_session *s = arg; 444 445 mta_connect(s); 446} 447 448static void 449mta_connect(struct mta_session *s) 450{ 451 struct sockaddr_storage ss; 452 struct sockaddr *sa; 453 int portno; 454 const char *schema; 455 456 if (s->helo == NULL) { 457 if (s->relay->helotable && s->route->src->sa) { 458 m_create(p_lka, IMSG_MTA_LOOKUP_HELO, 0, 0, -1); 459 m_add_id(p_lka, s->id); 460 m_add_string(p_lka, s->relay->helotable); 461 m_add_sockaddr(p_lka, s->route->src->sa); 462 m_close(p_lka); 463 tree_xset(&wait_helo, s->id, s); 464 s->flags |= MTA_WAIT; 465 return; 466 } 467 else if (s->relay->heloname) 468 s->helo = xstrdup(s->relay->heloname); 469 else 470 s->helo = xstrdup(env->sc_hostname); 471 } 472 473 if (s->io) { 474 io_free(s->io); 475 s->io = NULL; 476 } 477 478 s->use_smtps = s->use_starttls = s->use_smtp_tls = 0; 479 480 switch (s->attempt) { 481 case 0: 482 if (s->flags & MTA_FORCE_SMTPS) 483 s->use_smtps = 1; /* smtps */ 484 else if (s->flags & (MTA_FORCE_TLS|MTA_FORCE_ANYSSL)) 485 s->use_starttls = 1; /* tls, tls+smtps */ 486 else if (!(s->flags & MTA_FORCE_PLAIN)) 487 s->use_smtp_tls = 1; 488 break; 489 case 1: 490 if (s->flags & MTA_FORCE_ANYSSL) { 491 s->use_smtps = 1; /* tls+smtps */ 492 break; 493 } 494 else if (s->flags & MTA_DOWNGRADE_PLAIN) { 495 /* smtp, with tls failure */ 496 break; 497 } 498 default: 499 mta_free(s); 500 return; 501 } 502 portno = s->use_smtps ? 465 : 25; 503 504 /* Override with relay-specified port */ 505 if (s->relay->port) 506 portno = s->relay->port; 507 508 memmove(&ss, s->route->dst->sa, s->route->dst->sa->sa_len); 509 sa = (struct sockaddr *)&ss; 510 511 if (sa->sa_family == AF_INET) 512 ((struct sockaddr_in *)sa)->sin_port = htons(portno); 513 else if (sa->sa_family == AF_INET6) 514 ((struct sockaddr_in6 *)sa)->sin6_port = htons(portno); 515 516 s->attempt += 1; 517 if (s->use_smtp_tls) 518 schema = "smtp://"; 519 else if (s->use_starttls) 520 schema = "smtp+tls://"; 521 else if (s->use_smtps) 522 schema = "smtps://"; 523 else if (s->flags & MTA_LMTP) 524 schema = "lmtp://"; 525 else 526 schema = "smtp+notls://"; 527 528 log_info("%016"PRIx64" mta " 529 "connecting address=%s%s:%d host=%s", 530 s->id, schema, sa_to_text(s->route->dst->sa), 531 portno, s->route->dst->ptrname); 532 533 mta_enter_state(s, MTA_INIT); 534 s->io = io_new(); 535 io_set_callback(s->io, mta_io, s); 536 io_set_timeout(s->io, 300000); 537 if (io_connect(s->io, sa, s->route->src->sa) == -1) { 538 /* 539 * This error is most likely a "no route", 540 * so there is no need to try again. 541 */ 542 log_debug("debug: mta: io_connect failed: %s", io_error(s->io)); 543 if (errno == EADDRNOTAVAIL) 544 mta_source_error(s->relay, s->route, io_error(s->io)); 545 else 546 mta_error(s, "Connection failed: %s", io_error(s->io)); 547 mta_free(s); 548 } 549} 550 551static void 552mta_enter_state(struct mta_session *s, int newstate) 553{ 554 struct mta_envelope *e; 555 size_t envid_sz; 556 int oldstate; 557 ssize_t q; 558 char ibuf[LINE_MAX]; 559 char obuf[LINE_MAX]; 560 int offset; 561 const char *srs_sender; 562 563again: 564 oldstate = s->state; 565 566 log_trace(TRACE_MTA, "mta: %p: %s -> %s", s, 567 mta_strstate(oldstate), 568 mta_strstate(newstate)); 569 570 s->state = newstate; 571 572 memset(s->replybuf, 0, sizeof s->replybuf); 573 574 /* don't try this at home! */ 575#define mta_enter_state(_s, _st) do { newstate = _st; goto again; } while (0) 576 577 switch (s->state) { 578 case MTA_INIT: 579 case MTA_BANNER: 580 break; 581 582 case MTA_EHLO: 583 s->ext = 0; 584 mta_send(s, "EHLO %s", s->helo); 585 mta_report_link_identify(s, "EHLO", s->helo); 586 break; 587 588 case MTA_HELO: 589 s->ext = 0; 590 mta_send(s, "HELO %s", s->helo); 591 mta_report_link_identify(s, "HELO", s->helo); 592 break; 593 594 case MTA_LHLO: 595 s->ext = 0; 596 mta_send(s, "LHLO %s", s->helo); 597 mta_report_link_identify(s, "LHLO", s->helo); 598 break; 599 600 case MTA_STARTTLS: 601 if (s->flags & MTA_DOWNGRADE_PLAIN) 602 mta_enter_state(s, MTA_AUTH); 603 if (s->flags & MTA_TLS) /* already started */ 604 mta_enter_state(s, MTA_AUTH); 605 else if ((s->ext & MTA_EXT_STARTTLS) == 0) { 606 if (s->flags & MTA_FORCE_TLS || s->flags & MTA_WANT_SECURE) { 607 mta_error(s, "TLS required but not supported by remote host"); 608 s->flags |= MTA_RECONN; 609 } 610 else 611 /* server doesn't support starttls, do not use it */ 612 mta_enter_state(s, MTA_AUTH); 613 } 614 else 615 mta_send(s, "STARTTLS"); 616 break; 617 618 case MTA_AUTH: 619 if (s->relay->secret && s->flags & MTA_TLS) { 620 if (s->ext & MTA_EXT_AUTH) { 621 if (s->ext & MTA_EXT_AUTH_PLAIN) { 622 mta_enter_state(s, MTA_AUTH_PLAIN); 623 break; 624 } 625 if (s->ext & MTA_EXT_AUTH_LOGIN) { 626 mta_enter_state(s, MTA_AUTH_LOGIN); 627 break; 628 } 629 log_debug("debug: mta: %p: no supported AUTH method on session", s); 630 mta_error(s, "no supported AUTH method"); 631 } 632 else { 633 log_debug("debug: mta: %p: AUTH not advertised on session", s); 634 mta_error(s, "AUTH not advertised"); 635 } 636 } 637 else if (s->relay->secret) { 638 log_debug("debug: mta: %p: not using AUTH on non-TLS " 639 "session", s); 640 mta_error(s, "Refuse to AUTH over unsecure channel"); 641 mta_connect(s); 642 } else { 643 mta_enter_state(s, MTA_READY); 644 } 645 break; 646 647 case MTA_AUTH_PLAIN: 648 memset(ibuf, 0, sizeof ibuf); 649 if (base64_decode(s->relay->secret, (unsigned char *)ibuf, 650 sizeof(ibuf)-1) == -1) { 651 log_debug("debug: mta: %p: credentials too large on session", s); 652 mta_error(s, "Credentials too large"); 653 break; 654 } 655 s->username = xstrdup(ibuf+1); 656 mta_send(s, "AUTH PLAIN %s", s->relay->secret); 657 break; 658 659 case MTA_AUTH_LOGIN: 660 mta_send(s, "AUTH LOGIN"); 661 break; 662 663 case MTA_AUTH_LOGIN_USER: 664 memset(ibuf, 0, sizeof ibuf); 665 if (base64_decode(s->relay->secret, (unsigned char *)ibuf, 666 sizeof(ibuf)-1) == -1) { 667 log_debug("debug: mta: %p: credentials too large on session", s); 668 mta_error(s, "Credentials too large"); 669 break; 670 } 671 s->username = xstrdup(ibuf+1); 672 673 memset(obuf, 0, sizeof obuf); 674 base64_encode((unsigned char *)ibuf + 1, strlen(ibuf + 1), obuf, sizeof obuf); 675 mta_send(s, "%s", obuf); 676 677 memset(ibuf, 0, sizeof ibuf); 678 memset(obuf, 0, sizeof obuf); 679 break; 680 681 case MTA_AUTH_LOGIN_PASS: 682 memset(ibuf, 0, sizeof ibuf); 683 if (base64_decode(s->relay->secret, (unsigned char *)ibuf, 684 sizeof(ibuf)-1) == -1) { 685 log_debug("debug: mta: %p: credentials too large on session", s); 686 mta_error(s, "Credentials too large"); 687 break; 688 } 689 690 offset = strlen(ibuf+1)+2; 691 memset(obuf, 0, sizeof obuf); 692 base64_encode((unsigned char *)ibuf + offset, strlen(ibuf + offset), obuf, sizeof obuf); 693 mta_send(s, "%s", obuf); 694 695 memset(ibuf, 0, sizeof ibuf); 696 memset(obuf, 0, sizeof obuf); 697 break; 698 699 case MTA_READY: 700 /* Ready to send a new mail */ 701 if (s->ready == 0) { 702 s->ready = 1; 703 s->relay->nconn_ready += 1; 704 mta_route_ok(s->relay, s->route); 705 } 706 707 if (s->msgtried >= MAX_TRYBEFOREDISABLE) { 708 log_info("%016"PRIx64" mta host-rejects-all-mails", 709 s->id); 710 mta_route_down(s->relay, s->route); 711 mta_enter_state(s, MTA_QUIT); 712 break; 713 } 714 715 if (s->msgcount >= s->relay->limits->max_mail_per_session) { 716 log_debug("debug: mta: " 717 "%p: cannot send more message to relay %s", s, 718 mta_relay_to_text(s->relay)); 719 mta_enter_state(s, MTA_QUIT); 720 break; 721 } 722 723 /* 724 * When downgrading from opportunistic TLS, clear flag and 725 * possibly reuse the same task (forbidden in other cases). 726 */ 727 if (s->flags & MTA_DOWNGRADE_PLAIN) 728 s->flags &= ~MTA_DOWNGRADE_PLAIN; 729 else if (s->task) 730 fatalx("task should be NULL at this point"); 731 732 if (s->task == NULL) 733 s->task = mta_route_next_task(s->relay, s->route); 734 if (s->task == NULL) { 735 log_debug("debug: mta: %p: no task for relay %s", 736 s, mta_relay_to_text(s->relay)); 737 738 if (s->relay->nconn > 1 || 739 s->hangon >= s->relay->limits->sessdelay_keepalive) { 740 mta_enter_state(s, MTA_QUIT); 741 break; 742 } 743 744 log_debug("mta: debug: last connection: hanging on for %llds", 745 (long long)(s->relay->limits->sessdelay_keepalive - 746 s->hangon)); 747 s->flags |= MTA_HANGON; 748 runq_schedule(hangon, 1, s); 749 break; 750 } 751 752 log_debug("debug: mta: %p: handling next task for relay %s", s, 753 mta_relay_to_text(s->relay)); 754 755 stat_increment("mta.task.running", 1); 756 757 m_create(p_queue, IMSG_MTA_OPEN_MESSAGE, 0, 0, -1); 758 m_add_id(p_queue, s->id); 759 m_add_msgid(p_queue, s->task->msgid); 760 m_close(p_queue); 761 762 tree_xset(&wait_fd, s->id, s); 763 s->flags |= MTA_WAIT; 764 break; 765 766 case MTA_MAIL: 767 s->currevp = TAILQ_FIRST(&s->task->envelopes); 768 769 e = s->currevp; 770 s->hangon = 0; 771 s->msgtried++; 772 envid_sz = strlen(e->dsn_envid); 773 774 /* SRS-encode if requested for the relay action, AND we're not 775 * bouncing, AND we have an RCPT which means we are forwarded, 776 * AND the RCPT has a '@' just for sanity check (will always). 777 */ 778 if (env->sc_srs_key != NULL && 779 s->relay->srs && 780 strchr(s->task->sender, '@') && 781 e->rcpt && 782 strchr(e->rcpt, '@')) { 783 /* encode and replace task sender with new SRS-sender */ 784 srs_sender = srs_encode(s->task->sender, 785 strchr(e->rcpt, '@') + 1); 786 if (srs_sender) { 787 free(s->task->sender); 788 s->task->sender = xstrdup(srs_sender); 789 } 790 } 791 792 if (s->ext & MTA_EXT_DSN) { 793 mta_send(s, "MAIL FROM:<%s>%s%s%s%s", 794 s->task->sender, 795 e->dsn_ret ? " RET=" : "", 796 e->dsn_ret ? dsn_strret(e->dsn_ret) : "", 797 envid_sz ? " ENVID=" : "", 798 envid_sz ? e->dsn_envid : ""); 799 } else 800 mta_send(s, "MAIL FROM:<%s>", s->task->sender); 801 break; 802 803 case MTA_RCPT: 804 if (s->currevp == NULL) 805 s->currevp = TAILQ_FIRST(&s->task->envelopes); 806 807 e = s->currevp; 808 if (s->ext & MTA_EXT_DSN) { 809 mta_send(s, "RCPT TO:<%s>%s%s%s%s", 810 e->dest, 811 e->dsn_notify ? " NOTIFY=" : "", 812 e->dsn_notify ? dsn_strnotify(e->dsn_notify) : "", 813 e->dsn_orcpt ? " ORCPT=" : "", 814 e->dsn_orcpt ? e->dsn_orcpt : ""); 815 } else 816 mta_send(s, "RCPT TO:<%s>", e->dest); 817 818 mta_report_tx_envelope(s, s->task->msgid, e->id); 819 s->rcptcount++; 820 break; 821 822 case MTA_DATA: 823 fseek(s->datafp, 0, SEEK_SET); 824 mta_send(s, "DATA"); 825 break; 826 827 case MTA_BODY: 828 if (s->datafp == NULL) { 829 log_trace(TRACE_MTA, "mta: %p: end-of-file", s); 830 mta_enter_state(s, MTA_EOM); 831 break; 832 } 833 834 if ((q = mta_queue_data(s)) == -1) { 835 s->flags |= MTA_FREE; 836 break; 837 } 838 if (q == 0) { 839 mta_enter_state(s, MTA_BODY); 840 break; 841 } 842 843 log_trace(TRACE_MTA, "mta: %p: >>> [...%zd bytes...]", s, q); 844 break; 845 846 case MTA_EOM: 847 mta_send(s, "."); 848 break; 849 850 case MTA_LMTP_EOM: 851 /* LMTP reports status of each delivery, so enable read */ 852 io_set_read(s->io); 853 break; 854 855 case MTA_RSET: 856 if (s->datafp) { 857 fclose(s->datafp); 858 s->datafp = NULL; 859 s->datalen = 0; 860 } 861 mta_send(s, "RSET"); 862 break; 863 864 case MTA_QUIT: 865 mta_send(s, "QUIT"); 866 break; 867 868 default: 869 fatalx("mta_enter_state: unknown state"); 870 } 871#undef mta_enter_state 872} 873 874/* 875 * Handle a response to an SMTP command 876 */ 877static void 878mta_response(struct mta_session *s, char *line) 879{ 880 struct mta_envelope *e; 881 struct sockaddr_storage ss; 882 struct sockaddr *sa; 883 const char *domain; 884 char *pbuf; 885 socklen_t sa_len; 886 char buf[LINE_MAX]; 887 int delivery; 888 889 switch (s->state) { 890 891 case MTA_BANNER: 892 if (line[0] != '2') { 893 mta_error(s, "BANNER rejected: %s", line); 894 s->flags |= MTA_FREE; 895 return; 896 } 897 898 pbuf = ""; 899 if (strlen(line) > 4) { 900 (void)strlcpy(buf, line + 4, sizeof buf); 901 if ((pbuf = strchr(buf, ' '))) 902 *pbuf = '\0'; 903 pbuf = valid_domainpart(buf) ? buf : ""; 904 } 905 mta_report_link_greeting(s, pbuf); 906 907 if (s->flags & MTA_LMTP) 908 mta_enter_state(s, MTA_LHLO); 909 else 910 mta_enter_state(s, MTA_EHLO); 911 break; 912 913 case MTA_EHLO: 914 if (line[0] != '2') { 915 /* rejected at ehlo state */ 916 if ((s->relay->flags & RELAY_AUTH) || 917 (s->flags & MTA_WANT_SECURE)) { 918 mta_error(s, "EHLO rejected: %s", line); 919 s->flags |= MTA_FREE; 920 return; 921 } 922 mta_enter_state(s, MTA_HELO); 923 return; 924 } 925 if (!(s->flags & MTA_FORCE_PLAIN)) 926 mta_enter_state(s, MTA_STARTTLS); 927 else 928 mta_enter_state(s, MTA_READY); 929 break; 930 931 case MTA_HELO: 932 if (line[0] != '2') { 933 mta_error(s, "HELO rejected: %s", line); 934 s->flags |= MTA_FREE; 935 return; 936 } 937 mta_enter_state(s, MTA_READY); 938 break; 939 940 case MTA_LHLO: 941 if (line[0] != '2') { 942 mta_error(s, "LHLO rejected: %s", line); 943 s->flags |= MTA_FREE; 944 return; 945 } 946 mta_enter_state(s, MTA_READY); 947 break; 948 949 case MTA_STARTTLS: 950 if (line[0] != '2') { 951 if (!(s->flags & MTA_WANT_SECURE)) { 952 mta_enter_state(s, MTA_AUTH); 953 return; 954 } 955 /* XXX mark that the MX doesn't support STARTTLS */ 956 mta_error(s, "STARTTLS rejected: %s", line); 957 s->flags |= MTA_FREE; 958 return; 959 } 960 961 mta_tls_init(s); 962 break; 963 964 case MTA_AUTH_PLAIN: 965 if (line[0] != '2') { 966 mta_error(s, "AUTH rejected: %s", line); 967 mta_report_link_auth(s, s->username, "fail"); 968 s->flags |= MTA_FREE; 969 return; 970 } 971 mta_report_link_auth(s, s->username, "pass"); 972 mta_enter_state(s, MTA_READY); 973 break; 974 975 case MTA_AUTH_LOGIN: 976 if (strncmp(line, "334 ", 4) != 0) { 977 mta_error(s, "AUTH rejected: %s", line); 978 mta_report_link_auth(s, s->username, "fail"); 979 s->flags |= MTA_FREE; 980 return; 981 } 982 mta_enter_state(s, MTA_AUTH_LOGIN_USER); 983 break; 984 985 case MTA_AUTH_LOGIN_USER: 986 if (strncmp(line, "334 ", 4) != 0) { 987 mta_error(s, "AUTH rejected: %s", line); 988 mta_report_link_auth(s, s->username, "fail"); 989 s->flags |= MTA_FREE; 990 return; 991 } 992 mta_enter_state(s, MTA_AUTH_LOGIN_PASS); 993 break; 994 995 case MTA_AUTH_LOGIN_PASS: 996 if (line[0] != '2') { 997 mta_error(s, "AUTH rejected: %s", line); 998 mta_report_link_auth(s, s->username, "fail"); 999 s->flags |= MTA_FREE; 1000 return; 1001 } 1002 mta_report_link_auth(s, s->username, "pass"); 1003 mta_enter_state(s, MTA_READY); 1004 break; 1005 1006 case MTA_MAIL: 1007 if (line[0] != '2') { 1008 if (line[0] == '5') 1009 delivery = IMSG_MTA_DELIVERY_PERMFAIL; 1010 else 1011 delivery = IMSG_MTA_DELIVERY_TEMPFAIL; 1012 1013 mta_flush_task(s, delivery, line, 0, 0); 1014 mta_enter_state(s, MTA_RSET); 1015 return; 1016 } 1017 mta_report_tx_begin(s, s->task->msgid); 1018 mta_report_tx_mail(s, s->task->msgid, s->task->sender, 1); 1019 mta_enter_state(s, MTA_RCPT); 1020 break; 1021 1022 case MTA_RCPT: 1023 e = s->currevp; 1024 1025 /* remove envelope from hosttat cache if there */ 1026 if ((domain = strchr(e->dest, '@')) != NULL) { 1027 domain++; 1028 mta_hoststat_uncache(domain, e->id); 1029 } 1030 1031 s->currevp = TAILQ_NEXT(s->currevp, entry); 1032 if (line[0] == '2') { 1033 s->failures = 0; 1034 /* 1035 * this host is up, reschedule envelopes that 1036 * were cached for reschedule. 1037 */ 1038 if (domain) 1039 mta_hoststat_reschedule(domain); 1040 } 1041 else { 1042 mta_report_tx_rollback(s, s->task->msgid); 1043 mta_report_tx_reset(s, s->task->msgid); 1044 if (line[0] == '5') 1045 delivery = IMSG_MTA_DELIVERY_PERMFAIL; 1046 else 1047 delivery = IMSG_MTA_DELIVERY_TEMPFAIL; 1048 s->failures++; 1049 1050 /* remove failed envelope from task list */ 1051 TAILQ_REMOVE(&s->task->envelopes, e, entry); 1052 stat_decrement("mta.envelope", 1); 1053 1054 /* log right away */ 1055 (void)snprintf(buf, sizeof(buf), "%s", 1056 mta_host_to_text(s->route->dst)); 1057 1058 e->session = s->id; 1059 /* XXX */ 1060 /* 1061 * getsockname() can only fail with ENOBUFS here 1062 * best effort, don't log source ... 1063 */ 1064 sa_len = sizeof(ss); 1065 sa = (struct sockaddr *)&ss; 1066 if (getsockname(io_fileno(s->io), sa, &sa_len) == -1) 1067 mta_delivery_log(e, NULL, buf, delivery, line); 1068 else 1069 mta_delivery_log(e, sa_to_text(sa), 1070 buf, delivery, line); 1071 1072 if (domain) 1073 mta_hoststat_update(domain, e->status); 1074 mta_delivery_notify(e); 1075 1076 if (s->relay->limits->max_failures_per_session && 1077 s->failures == s->relay->limits->max_failures_per_session) { 1078 mta_flush_task(s, IMSG_MTA_DELIVERY_TEMPFAIL, 1079 "Too many consecutive errors, closing connection", 0, 1); 1080 mta_enter_state(s, MTA_QUIT); 1081 break; 1082 } 1083 1084 /* 1085 * if no more envelopes, flush failed queue 1086 */ 1087 if (TAILQ_EMPTY(&s->task->envelopes)) { 1088 mta_flush_task(s, IMSG_MTA_DELIVERY_OK, 1089 "No envelope", 0, 0); 1090 mta_enter_state(s, MTA_RSET); 1091 break; 1092 } 1093 } 1094 1095 switch (line[0]) { 1096 case '2': 1097 mta_report_tx_rcpt(s, 1098 s->task->msgid, e->dest, 1); 1099 break; 1100 case '4': 1101 mta_report_tx_rcpt(s, 1102 s->task->msgid, e->dest, -1); 1103 break; 1104 case '5': 1105 mta_report_tx_rcpt(s, 1106 s->task->msgid, e->dest, 0); 1107 break; 1108 } 1109 1110 if (s->currevp == NULL) 1111 mta_enter_state(s, MTA_DATA); 1112 else 1113 mta_enter_state(s, MTA_RCPT); 1114 break; 1115 1116 case MTA_DATA: 1117 if (line[0] == '2' || line[0] == '3') { 1118 mta_report_tx_data(s, s->task->msgid, 1); 1119 mta_enter_state(s, MTA_BODY); 1120 break; 1121 } 1122 1123 if (line[0] == '5') 1124 delivery = IMSG_MTA_DELIVERY_PERMFAIL; 1125 else 1126 delivery = IMSG_MTA_DELIVERY_TEMPFAIL; 1127 mta_report_tx_data(s, s->task->msgid, 1128 delivery == IMSG_MTA_DELIVERY_TEMPFAIL ? -1 : 0); 1129 mta_report_tx_rollback(s, s->task->msgid); 1130 mta_report_tx_reset(s, s->task->msgid); 1131 mta_flush_task(s, delivery, line, 0, 0); 1132 mta_enter_state(s, MTA_RSET); 1133 break; 1134 1135 case MTA_LMTP_EOM: 1136 case MTA_EOM: 1137 if (line[0] == '2') { 1138 delivery = IMSG_MTA_DELIVERY_OK; 1139 s->msgtried = 0; 1140 s->msgcount++; 1141 } 1142 else if (line[0] == '5') 1143 delivery = IMSG_MTA_DELIVERY_PERMFAIL; 1144 else 1145 delivery = IMSG_MTA_DELIVERY_TEMPFAIL; 1146 if (delivery != IMSG_MTA_DELIVERY_OK) { 1147 mta_report_tx_rollback(s, s->task->msgid); 1148 mta_report_tx_reset(s, s->task->msgid); 1149 } 1150 else { 1151 mta_report_tx_commit(s, s->task->msgid, s->datalen); 1152 mta_report_tx_reset(s, s->task->msgid); 1153 } 1154 mta_flush_task(s, delivery, line, (s->flags & MTA_LMTP) ? 1 : 0, 0); 1155 if (s->task) { 1156 s->rcptcount--; 1157 mta_enter_state(s, MTA_LMTP_EOM); 1158 } else { 1159 s->rcptcount = 0; 1160 if (s->relay->limits->sessdelay_transaction) { 1161 log_debug("debug: mta: waiting for %llds before next transaction", 1162 (long long)s->relay->limits->sessdelay_transaction); 1163 s->hangon = s->relay->limits->sessdelay_transaction -1; 1164 s->flags |= MTA_HANGON; 1165 runq_schedule(hangon, 1166 s->relay->limits->sessdelay_transaction, s); 1167 } 1168 else 1169 mta_enter_state(s, MTA_READY); 1170 } 1171 break; 1172 1173 case MTA_RSET: 1174 s->rcptcount = 0; 1175 1176 if (s->task) { 1177 mta_report_tx_rollback(s, s->task->msgid); 1178 mta_report_tx_reset(s, s->task->msgid); 1179 } 1180 if (s->relay->limits->sessdelay_transaction) { 1181 log_debug("debug: mta: waiting for %llds after reset", 1182 (long long)s->relay->limits->sessdelay_transaction); 1183 s->hangon = s->relay->limits->sessdelay_transaction -1; 1184 s->flags |= MTA_HANGON; 1185 runq_schedule(hangon, 1186 s->relay->limits->sessdelay_transaction, s); 1187 } 1188 else 1189 mta_enter_state(s, MTA_READY); 1190 break; 1191 1192 default: 1193 fatalx("mta_response() bad state"); 1194 } 1195} 1196 1197static void 1198mta_io(struct io *io, int evt, void *arg) 1199{ 1200 struct mta_session *s = arg; 1201 char *line, *msg, *p; 1202 size_t len; 1203 const char *error; 1204 int cont; 1205 1206 log_trace(TRACE_IO, "mta: %p: %s %s", s, io_strevent(evt), 1207 io_strio(io)); 1208 1209 switch (evt) { 1210 1211 case IO_CONNECTED: 1212 mta_connected(s); 1213 1214 if (s->use_smtps) { 1215 io_set_write(io); 1216 mta_tls_init(s); 1217 if (s->flags & MTA_FREE) 1218 mta_free(s); 1219 } 1220 else { 1221 mta_enter_state(s, MTA_BANNER); 1222 io_set_read(io); 1223 } 1224 break; 1225 1226 case IO_TLSREADY: 1227 log_info("%016"PRIx64" mta tls ciphers=%s", 1228 s->id, tls_to_text(io_tls(s->io))); 1229 s->flags |= MTA_TLS; 1230 if (s->relay->dispatcher->u.remote.tls_verify) 1231 s->flags |= MTA_TLS_VERIFIED; 1232 1233 mta_tls_started(s); 1234 mta_report_link_tls(s, 1235 tls_to_text(io_tls(s->io))); 1236 break; 1237 1238 case IO_DATAIN: 1239 nextline: 1240 line = io_getline(s->io, &len); 1241 if (line == NULL) { 1242 if (io_datalen(s->io) >= LINE_MAX) { 1243 mta_error(s, "Input too long"); 1244 mta_free(s); 1245 } 1246 return; 1247 } 1248 1249 /* Strip trailing '\r' */ 1250 if (len && line[len - 1] == '\r') 1251 line[--len] = '\0'; 1252 1253 log_trace(TRACE_MTA, "mta: %p: <<< %s", s, line); 1254 mta_report_protocol_server(s, line); 1255 1256 if ((error = parse_smtp_response(line, len, &msg, &cont))) { 1257 mta_error(s, "Bad response: %s", error); 1258 mta_free(s); 1259 return; 1260 } 1261 1262 /* read extensions */ 1263 if (s->state == MTA_EHLO) { 1264 if (strcmp(msg, "STARTTLS") == 0) 1265 s->ext |= MTA_EXT_STARTTLS; 1266 else if (strncmp(msg, "AUTH ", 5) == 0) { 1267 s->ext |= MTA_EXT_AUTH; 1268 if ((p = strstr(msg, " PLAIN")) && 1269 (*(p+6) == '\0' || *(p+6) == ' ')) 1270 s->ext |= MTA_EXT_AUTH_PLAIN; 1271 if ((p = strstr(msg, " LOGIN")) && 1272 (*(p+6) == '\0' || *(p+6) == ' ')) 1273 s->ext |= MTA_EXT_AUTH_LOGIN; 1274 } 1275 else if (strcmp(msg, "PIPELINING") == 0) 1276 s->ext |= MTA_EXT_PIPELINING; 1277 else if (strcmp(msg, "DSN") == 0) 1278 s->ext |= MTA_EXT_DSN; 1279 else if (strncmp(msg, "SIZE ", 5) == 0) { 1280 s->ext_size = strtonum(msg+5, 0, UINT32_MAX, &error); 1281 if (error == NULL) 1282 s->ext |= MTA_EXT_SIZE; 1283 } 1284 } 1285 1286 /* continuation reply, we parse out the repeating statuses and ESC */ 1287 if (cont) { 1288 if (s->replybuf[0] == '\0') 1289 (void)strlcat(s->replybuf, line, sizeof s->replybuf); 1290 else if (len > 4) { 1291 p = line + 4; 1292 if (isdigit((unsigned char)p[0]) && p[1] == '.' && 1293 isdigit((unsigned char)p[2]) && p[3] == '.' && 1294 isdigit((unsigned char)p[4]) && isspace((unsigned char)p[5])) 1295 p += 5; 1296 (void)strlcat(s->replybuf, p, sizeof s->replybuf); 1297 } 1298 goto nextline; 1299 } 1300 1301 /* last line of a reply, check if we're on a continuation to parse out status and ESC. 1302 * if we overflow reply buffer or are not on continuation, log entire last line. 1303 */ 1304 if (s->replybuf[0] == '\0') 1305 (void)strlcat(s->replybuf, line, sizeof s->replybuf); 1306 else if (len > 4) { 1307 p = line + 4; 1308 if (isdigit((unsigned char)p[0]) && p[1] == '.' && 1309 isdigit((unsigned char)p[2]) && p[3] == '.' && 1310 isdigit((unsigned char)p[4]) && isspace((unsigned char)p[5])) 1311 p += 5; 1312 if (strlcat(s->replybuf, p, sizeof s->replybuf) >= sizeof s->replybuf) 1313 (void)strlcpy(s->replybuf, line, sizeof s->replybuf); 1314 } 1315 1316 if (s->state == MTA_QUIT) { 1317 log_info("%016"PRIx64" mta disconnected reason=quit messages=%zu", 1318 s->id, s->msgcount); 1319 mta_free(s); 1320 return; 1321 } 1322 io_set_write(io); 1323 mta_response(s, s->replybuf); 1324 if (s->flags & MTA_FREE) { 1325 mta_free(s); 1326 return; 1327 } 1328 if (s->flags & MTA_RECONN) { 1329 s->flags &= ~MTA_RECONN; 1330 mta_connect(s); 1331 return; 1332 } 1333 1334 if (io_datalen(s->io)) { 1335 log_debug("debug: mta: remaining data in input buffer"); 1336 mta_error(s, "Remote host sent too much data"); 1337 if (s->flags & MTA_WAIT) 1338 s->flags |= MTA_FREE; 1339 else 1340 mta_free(s); 1341 } 1342 break; 1343 1344 case IO_LOWAT: 1345 if (s->state == MTA_BODY) { 1346 mta_enter_state(s, MTA_BODY); 1347 if (s->flags & MTA_FREE) { 1348 mta_free(s); 1349 return; 1350 } 1351 } 1352 1353 if (io_queued(s->io) == 0) 1354 io_set_read(io); 1355 break; 1356 1357 case IO_TIMEOUT: 1358 log_debug("debug: mta: %p: connection timeout", s); 1359 mta_error(s, "Connection timeout"); 1360 mta_report_timeout(s); 1361 if (!s->ready) 1362 mta_connect(s); 1363 else 1364 mta_free(s); 1365 break; 1366 1367 case IO_ERROR: 1368 log_debug("debug: mta: %p: IO error: %s", s, io_error(io)); 1369 1370 if (s->state == MTA_STARTTLS && s->use_smtp_tls) { 1371 /* error in non-strict SSL negotiation, downgrade to plain */ 1372 log_info("smtp-out: Error on session %016"PRIx64 1373 ": opportunistic TLS failed, " 1374 "downgrading to plain", s->id); 1375 s->flags &= ~MTA_TLS; 1376 s->flags |= MTA_DOWNGRADE_PLAIN; 1377 mta_connect(s); 1378 break; 1379 } 1380 1381 mta_error(s, "IO Error: %s", io_error(io)); 1382 mta_free(s); 1383 break; 1384 1385 case IO_DISCONNECTED: 1386 log_debug("debug: mta: %p: disconnected in state %s", 1387 s, mta_strstate(s->state)); 1388 mta_error(s, "Connection closed unexpectedly"); 1389 if (!s->ready) 1390 mta_connect(s); 1391 else 1392 mta_free(s); 1393 break; 1394 1395 default: 1396 fatalx("mta_io() bad event"); 1397 } 1398} 1399 1400static void 1401mta_send(struct mta_session *s, char *fmt, ...) 1402{ 1403 va_list ap; 1404 char *p; 1405 int len; 1406 1407 va_start(ap, fmt); 1408 if ((len = vasprintf(&p, fmt, ap)) == -1) 1409 fatal("mta: vasprintf"); 1410 va_end(ap); 1411 1412 log_trace(TRACE_MTA, "mta: %p: >>> %s", s, p); 1413 1414 if (strncasecmp(p, "AUTH PLAIN ", 11) == 0) 1415 mta_report_protocol_client(s, "AUTH PLAIN ********"); 1416 else if (s->state == MTA_AUTH_LOGIN_USER || s->state == MTA_AUTH_LOGIN_PASS) 1417 mta_report_protocol_client(s, "********"); 1418 else 1419 mta_report_protocol_client(s, p); 1420 1421 io_xprintf(s->io, "%s\r\n", p); 1422 1423 free(p); 1424} 1425 1426/* 1427 * Queue some data into the input buffer 1428 */ 1429static ssize_t 1430mta_queue_data(struct mta_session *s) 1431{ 1432 char *ln = NULL; 1433 size_t sz = 0, q; 1434 ssize_t len; 1435 1436 q = io_queued(s->io); 1437 1438 while (io_queued(s->io) < MTA_HIWAT) { 1439 if ((len = getline(&ln, &sz, s->datafp)) == -1) 1440 break; 1441 if (ln[len - 1] == '\n') 1442 ln[len - 1] = '\0'; 1443 s->datalen += io_xprintf(s->io, "%s%s\r\n", *ln == '.' ? "." : "", ln); 1444 } 1445 1446 free(ln); 1447 if (ferror(s->datafp)) { 1448 mta_flush_task(s, IMSG_MTA_DELIVERY_TEMPFAIL, 1449 "Error reading content file", 0, 0); 1450 return (-1); 1451 } 1452 1453 if (feof(s->datafp)) { 1454 fclose(s->datafp); 1455 s->datafp = NULL; 1456 } 1457 1458 return (io_queued(s->io) - q); 1459} 1460 1461static void 1462mta_flush_task(struct mta_session *s, int delivery, const char *error, size_t count, 1463 int cache) 1464{ 1465 struct mta_envelope *e; 1466 char relay[LINE_MAX]; 1467 size_t n; 1468 struct sockaddr_storage ss; 1469 struct sockaddr *sa; 1470 socklen_t sa_len; 1471 const char *domain; 1472 1473 (void)snprintf(relay, sizeof relay, "%s", mta_host_to_text(s->route->dst)); 1474 n = 0; 1475 while ((e = TAILQ_FIRST(&s->task->envelopes))) { 1476 1477 if (count && n == count) { 1478 stat_decrement("mta.envelope", n); 1479 return; 1480 } 1481 1482 TAILQ_REMOVE(&s->task->envelopes, e, entry); 1483 1484 /* we're about to log, associate session to envelope */ 1485 e->session = s->id; 1486 e->ext = s->ext; 1487 1488 /* XXX */ 1489 /* 1490 * getsockname() can only fail with ENOBUFS here 1491 * best effort, don't log source ... 1492 */ 1493 sa = (struct sockaddr *)&ss; 1494 sa_len = sizeof(ss); 1495 if (getsockname(io_fileno(s->io), sa, &sa_len) == -1) 1496 mta_delivery_log(e, NULL, relay, delivery, error); 1497 else 1498 mta_delivery_log(e, sa_to_text(sa), 1499 relay, delivery, error); 1500 1501 mta_delivery_notify(e); 1502 1503 domain = strchr(e->dest, '@'); 1504 if (domain) { 1505 domain++; 1506 mta_hoststat_update(domain, error); 1507 if (cache) 1508 mta_hoststat_cache(domain, e->id); 1509 } 1510 1511 n++; 1512 } 1513 1514 free(s->task->sender); 1515 free(s->task); 1516 s->task = NULL; 1517 1518 if (s->datafp) { 1519 fclose(s->datafp); 1520 s->datafp = NULL; 1521 } 1522 1523 stat_decrement("mta.envelope", n); 1524 stat_decrement("mta.task.running", 1); 1525 stat_decrement("mta.task", 1); 1526} 1527 1528static void 1529mta_error(struct mta_session *s, const char *fmt, ...) 1530{ 1531 va_list ap; 1532 char *error; 1533 int len; 1534 1535 va_start(ap, fmt); 1536 if ((len = vasprintf(&error, fmt, ap)) == -1) 1537 fatal("mta: vasprintf"); 1538 va_end(ap); 1539 1540 if (s->msgcount) 1541 log_info("smtp-out: Error on session %016"PRIx64 1542 " after %zu message%s sent: %s", s->id, s->msgcount, 1543 (s->msgcount > 1) ? "s" : "", error); 1544 else 1545 log_info("%016"PRIx64" mta error reason=%s", 1546 s->id, error); 1547 1548 /* 1549 * If not connected yet, and the error is not local, just ignore it 1550 * and try to reconnect. 1551 */ 1552 if (s->state == MTA_INIT && 1553 (errno == ETIMEDOUT || errno == ECONNREFUSED)) { 1554 log_debug("debug: mta: not reporting route error yet"); 1555 free(error); 1556 return; 1557 } 1558 1559 mta_route_error(s->relay, s->route); 1560 1561 if (s->task) 1562 mta_flush_task(s, IMSG_MTA_DELIVERY_TEMPFAIL, error, 0, 0); 1563 1564 free(error); 1565} 1566 1567static void 1568mta_tls_init(struct mta_session *s) 1569{ 1570 struct dispatcher_remote *remote; 1571 struct tls *tls; 1572 1573 if ((tls = tls_client()) == NULL) { 1574 log_info("%016"PRIx64" mta closing reason=tls-failure", s->id); 1575 s->flags |= MTA_FREE; 1576 return; 1577 } 1578 1579 remote = &s->relay->dispatcher->u.remote; 1580 if ((s->flags & MTA_WANT_SECURE) && !remote->tls_required) { 1581 /* If TLS not explicitly configured, use implicit config. */ 1582 remote->tls_required = 1; 1583 remote->tls_verify = 1; 1584 tls_config_verify(remote->tls_config); 1585 } 1586 if (tls_configure(tls, remote->tls_config) == -1) { 1587 log_info("%016"PRIx64" mta closing reason=tls-failure", s->id); 1588 tls_free(tls); 1589 s->flags |= MTA_FREE; 1590 return; 1591 } 1592 1593 if (io_connect_tls(s->io, tls, s->mxname) == -1) { 1594 log_info("%016"PRIx64" mta closing reason=tls-connect-failed", s->id); 1595 tls_free(tls); 1596 s->flags |= MTA_FREE; 1597 } 1598} 1599 1600static void 1601mta_tls_started(struct mta_session *s) 1602{ 1603 if (tls_peer_cert_provided(io_tls(s->io))) { 1604 log_info("%016"PRIx64" mta " 1605 "cert-check result=\"%s\" fingerprint=\"%s\"", 1606 s->id, 1607 (s->flags & MTA_TLS_VERIFIED) ? "valid" : "unverified", 1608 tls_peer_cert_hash(io_tls(s->io))); 1609 } 1610 else { 1611 log_info("%016"PRIx64" smtp " 1612 "cert-check result=\"no certificate presented\"", 1613 s->id); 1614 } 1615 1616 if (s->use_smtps) { 1617 mta_enter_state(s, MTA_BANNER); 1618 io_set_read(s->io); 1619 } 1620 else 1621 mta_enter_state(s, MTA_EHLO); 1622} 1623 1624static const char * 1625dsn_strret(enum dsn_ret ret) 1626{ 1627 if (ret == DSN_RETHDRS) 1628 return "HDRS"; 1629 else if (ret == DSN_RETFULL) 1630 return "FULL"; 1631 else { 1632 log_debug("mta: invalid ret %d", ret); 1633 return "???"; 1634 } 1635} 1636 1637static const char * 1638dsn_strnotify(uint8_t arg) 1639{ 1640 static char buf[32]; 1641 size_t sz; 1642 1643 buf[0] = '\0'; 1644 if (arg & DSN_SUCCESS) 1645 (void)strlcat(buf, "SUCCESS,", sizeof(buf)); 1646 1647 if (arg & DSN_FAILURE) 1648 (void)strlcat(buf, "FAILURE,", sizeof(buf)); 1649 1650 if (arg & DSN_DELAY) 1651 (void)strlcat(buf, "DELAY,", sizeof(buf)); 1652 1653 if (arg & DSN_NEVER) 1654 (void)strlcat(buf, "NEVER,", sizeof(buf)); 1655 1656 /* trim trailing comma */ 1657 sz = strlen(buf); 1658 if (sz) 1659 buf[sz - 1] = '\0'; 1660 1661 return (buf); 1662} 1663 1664#define CASE(x) case x : return #x 1665 1666static const char * 1667mta_strstate(int state) 1668{ 1669 switch (state) { 1670 CASE(MTA_INIT); 1671 CASE(MTA_BANNER); 1672 CASE(MTA_EHLO); 1673 CASE(MTA_HELO); 1674 CASE(MTA_STARTTLS); 1675 CASE(MTA_AUTH); 1676 CASE(MTA_AUTH_PLAIN); 1677 CASE(MTA_AUTH_LOGIN); 1678 CASE(MTA_AUTH_LOGIN_USER); 1679 CASE(MTA_AUTH_LOGIN_PASS); 1680 CASE(MTA_READY); 1681 CASE(MTA_MAIL); 1682 CASE(MTA_RCPT); 1683 CASE(MTA_DATA); 1684 CASE(MTA_BODY); 1685 CASE(MTA_EOM); 1686 CASE(MTA_LMTP_EOM); 1687 CASE(MTA_RSET); 1688 CASE(MTA_QUIT); 1689 default: 1690 return "MTA_???"; 1691 } 1692} 1693 1694static void 1695mta_filter_begin(struct mta_session *s) 1696{ 1697 if (!SESSION_FILTERED(s)) 1698 return; 1699 1700 m_create(p_lka, IMSG_FILTER_SMTP_BEGIN, 0, 0, -1); 1701 m_add_id(p_lka, s->id); 1702 m_add_string(p_lka, s->relay->dispatcher->u.remote.filtername); 1703 m_close(p_lka); 1704} 1705 1706static void 1707mta_filter_end(struct mta_session *s) 1708{ 1709 if (!SESSION_FILTERED(s)) 1710 return; 1711 1712 m_create(p_lka, IMSG_FILTER_SMTP_END, 0, 0, -1); 1713 m_add_id(p_lka, s->id); 1714 m_close(p_lka); 1715} 1716 1717static void 1718mta_connected(struct mta_session *s) 1719{ 1720 struct sockaddr_storage sa_src; 1721 struct sockaddr_storage sa_dest; 1722 int sa_len; 1723 1724 log_info("%016"PRIx64" mta connected", s->id); 1725 1726 sa_len = sizeof sa_src; 1727 if (getsockname(io_fileno(s->io), 1728 (struct sockaddr *)&sa_src, &sa_len) == -1) 1729 bzero(&sa_src, sizeof sa_src); 1730 sa_len = sizeof sa_dest; 1731 if (getpeername(io_fileno(s->io), 1732 (struct sockaddr *)&sa_dest, &sa_len) == -1) 1733 bzero(&sa_dest, sizeof sa_dest); 1734 1735 mta_report_link_connect(s, 1736 s->route->dst->ptrname, 1, 1737 &sa_src, 1738 &sa_dest); 1739} 1740 1741static void 1742mta_disconnected(struct mta_session *s) 1743{ 1744 mta_report_link_disconnect(s); 1745 mta_filter_end(s); 1746} 1747 1748 1749static void 1750mta_report_link_connect(struct mta_session *s, const char *rdns, int fcrdns, 1751 const struct sockaddr_storage *ss_src, 1752 const struct sockaddr_storage *ss_dest) 1753{ 1754 if (! SESSION_FILTERED(s)) 1755 return; 1756 1757 report_smtp_link_connect("smtp-out", s->id, rdns, fcrdns, ss_src, ss_dest); 1758} 1759 1760static void 1761mta_report_link_greeting(struct mta_session *s, 1762 const char *domain) 1763{ 1764 if (! SESSION_FILTERED(s)) 1765 return; 1766 1767 report_smtp_link_greeting("smtp-out", s->id, domain); 1768} 1769 1770static void 1771mta_report_link_identify(struct mta_session *s, const char *method, const char *identity) 1772{ 1773 if (! SESSION_FILTERED(s)) 1774 return; 1775 1776 report_smtp_link_identify("smtp-out", s->id, method, identity); 1777} 1778 1779static void 1780mta_report_link_tls(struct mta_session *s, const char *ssl) 1781{ 1782 if (! SESSION_FILTERED(s)) 1783 return; 1784 1785 report_smtp_link_tls("smtp-out", s->id, ssl); 1786} 1787 1788static void 1789mta_report_link_disconnect(struct mta_session *s) 1790{ 1791 if (! SESSION_FILTERED(s)) 1792 return; 1793 1794 report_smtp_link_disconnect("smtp-out", s->id); 1795} 1796 1797static void 1798mta_report_link_auth(struct mta_session *s, const char *user, const char *result) 1799{ 1800 if (! SESSION_FILTERED(s)) 1801 return; 1802 1803 report_smtp_link_auth("smtp-out", s->id, user, result); 1804} 1805 1806static void 1807mta_report_tx_reset(struct mta_session *s, uint32_t msgid) 1808{ 1809 if (! SESSION_FILTERED(s)) 1810 return; 1811 1812 report_smtp_tx_reset("smtp-out", s->id, msgid); 1813} 1814 1815static void 1816mta_report_tx_begin(struct mta_session *s, uint32_t msgid) 1817{ 1818 if (! SESSION_FILTERED(s)) 1819 return; 1820 1821 report_smtp_tx_begin("smtp-out", s->id, msgid); 1822} 1823 1824static void 1825mta_report_tx_mail(struct mta_session *s, uint32_t msgid, const char *address, int ok) 1826{ 1827 if (! SESSION_FILTERED(s)) 1828 return; 1829 1830 report_smtp_tx_mail("smtp-out", s->id, msgid, address, ok); 1831} 1832 1833static void 1834mta_report_tx_rcpt(struct mta_session *s, uint32_t msgid, const char *address, int ok) 1835{ 1836 if (! SESSION_FILTERED(s)) 1837 return; 1838 1839 report_smtp_tx_rcpt("smtp-out", s->id, msgid, address, ok); 1840} 1841 1842static void 1843mta_report_tx_envelope(struct mta_session *s, uint32_t msgid, uint64_t evpid) 1844{ 1845 if (! SESSION_FILTERED(s)) 1846 return; 1847 1848 report_smtp_tx_envelope("smtp-out", s->id, msgid, evpid); 1849} 1850 1851static void 1852mta_report_tx_data(struct mta_session *s, uint32_t msgid, int ok) 1853{ 1854 if (! SESSION_FILTERED(s)) 1855 return; 1856 1857 report_smtp_tx_data("smtp-out", s->id, msgid, ok); 1858} 1859 1860static void 1861mta_report_tx_commit(struct mta_session *s, uint32_t msgid, size_t msgsz) 1862{ 1863 if (! SESSION_FILTERED(s)) 1864 return; 1865 1866 report_smtp_tx_commit("smtp-out", s->id, msgid, msgsz); 1867} 1868 1869static void 1870mta_report_tx_rollback(struct mta_session *s, uint32_t msgid) 1871{ 1872 if (! SESSION_FILTERED(s)) 1873 return; 1874 1875 report_smtp_tx_rollback("smtp-out", s->id, msgid); 1876} 1877 1878static void 1879mta_report_protocol_client(struct mta_session *s, const char *command) 1880{ 1881 if (! SESSION_FILTERED(s)) 1882 return; 1883 1884 report_smtp_protocol_client("smtp-out", s->id, command); 1885} 1886 1887static void 1888mta_report_protocol_server(struct mta_session *s, const char *response) 1889{ 1890 if (! SESSION_FILTERED(s)) 1891 return; 1892 1893 report_smtp_protocol_server("smtp-out", s->id, response); 1894} 1895 1896#if 0 1897static void 1898mta_report_filter_response(struct mta_session *s, int phase, int response, const char *param) 1899{ 1900 if (! SESSION_FILTERED(s)) 1901 return; 1902 1903 report_smtp_filter_response("smtp-out", s->id, phase, response, param); 1904} 1905#endif 1906 1907static void 1908mta_report_timeout(struct mta_session *s) 1909{ 1910 if (! SESSION_FILTERED(s)) 1911 return; 1912 1913 report_smtp_timeout("smtp-out", s->id); 1914} 1915