1 /* $OpenBSD: smtp_session.c,v 1.285 2016/07/29 08:53:07 giovanni Exp $ */ 2 3 /* 4 * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org> 5 * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> 6 * Copyright (c) 2008-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/types.h> 23 #include <sys/queue.h> 24 #include <sys/tree.h> 25 #include <sys/socket.h> 26 #include <sys/uio.h> 27 28 #include <netinet/in.h> 29 30 #include <ctype.h> 31 #include <errno.h> 32 #include <event.h> 33 #include <imsg.h> 34 #include <limits.h> 35 #include <inttypes.h> 36 #include <openssl/ssl.h> 37 #include <resolv.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <unistd.h> 42 #include <vis.h> 43 44 #include "smtpd.h" 45 #include "log.h" 46 #include "ssl.h" 47 48 #define DATA_HIWAT 65535 49 #define APPEND_DOMAIN_BUFFER_SIZE 4096 50 51 enum smtp_phase { 52 PHASE_INIT = 0, 53 PHASE_SETUP, 54 PHASE_TRANSACTION 55 }; 56 57 enum smtp_state { 58 STATE_NEW = 0, 59 STATE_CONNECTED, 60 STATE_TLS, 61 STATE_HELO, 62 STATE_AUTH_INIT, 63 STATE_AUTH_USERNAME, 64 STATE_AUTH_PASSWORD, 65 STATE_AUTH_FINALIZE, 66 STATE_BODY, 67 STATE_QUIT, 68 }; 69 70 enum session_flags { 71 SF_EHLO = 0x0001, 72 SF_8BITMIME = 0x0002, 73 SF_SECURE = 0x0004, 74 SF_AUTHENTICATED = 0x0008, 75 SF_BOUNCE = 0x0010, 76 SF_VERIFIED = 0x0020, 77 SF_BADINPUT = 0x0080, 78 SF_FILTERCONN = 0x0100, 79 SF_FILTERDATA = 0x0200, 80 SF_FILTERTX = 0x0400, 81 }; 82 83 enum message_flags { 84 MF_QUEUE_ENVELOPE_FAIL = 0x00001, 85 MF_ERROR_SIZE = 0x01000, 86 MF_ERROR_IO = 0x02000, 87 MF_ERROR_LOOP = 0x04000, 88 MF_ERROR_MALFORMED = 0x08000, 89 MF_ERROR_RESOURCES = 0x10000, 90 }; 91 #define MF_ERROR (MF_ERROR_SIZE | MF_ERROR_IO | MF_ERROR_LOOP | MF_ERROR_MALFORMED | MF_ERROR_RESOURCES) 92 93 enum smtp_command { 94 CMD_HELO = 0, 95 CMD_EHLO, 96 CMD_STARTTLS, 97 CMD_AUTH, 98 CMD_MAIL_FROM, 99 CMD_RCPT_TO, 100 CMD_DATA, 101 CMD_RSET, 102 CMD_QUIT, 103 CMD_HELP, 104 CMD_WIZ, 105 CMD_NOOP, 106 }; 107 108 struct smtp_rcpt { 109 TAILQ_ENTRY(smtp_rcpt) entry; 110 struct mailaddr maddr; 111 size_t destcount; 112 }; 113 114 struct smtp_tx { 115 struct smtp_session *session; 116 uint32_t msgid; 117 118 struct envelope evp; 119 size_t rcptcount; 120 size_t destcount; 121 TAILQ_HEAD(, smtp_rcpt) rcpts; 122 123 size_t datain; 124 size_t odatalen; 125 struct iobuf obuf; 126 struct io oev; 127 int hdrdone; 128 int rcvcount; 129 int dataeom; 130 131 int msgflags; 132 int msgcode; 133 134 int skiphdr; 135 struct rfc2822_parser rfc2822_parser; 136 }; 137 138 struct smtp_session { 139 uint64_t id; 140 struct iobuf iobuf; 141 struct io io; 142 struct listener *listener; 143 void *ssl_ctx; 144 struct sockaddr_storage ss; 145 char hostname[HOST_NAME_MAX+1]; 146 char smtpname[HOST_NAME_MAX+1]; 147 148 int flags; 149 int phase; 150 enum smtp_state state; 151 152 char helo[LINE_MAX]; 153 char cmd[LINE_MAX]; 154 char username[SMTPD_MAXMAILADDRSIZE]; 155 156 size_t mailcount; 157 struct event pause; 158 159 struct smtp_tx *tx; 160 }; 161 162 #define ADVERTISE_TLS(s) \ 163 ((s)->listener->flags & F_STARTTLS && !((s)->flags & SF_SECURE)) 164 165 #define ADVERTISE_AUTH(s) \ 166 ((s)->listener->flags & F_AUTH && (s)->flags & SF_SECURE && \ 167 !((s)->flags & SF_AUTHENTICATED)) 168 169 #define ADVERTISE_EXT_DSN(s) \ 170 ((s)->listener->flags & F_EXT_DSN) 171 172 static int smtp_mailaddr(struct mailaddr *, char *, int, char **, const char *); 173 static void smtp_session_init(void); 174 static int smtp_lookup_servername(struct smtp_session *); 175 static void smtp_connected(struct smtp_session *); 176 static void smtp_send_banner(struct smtp_session *); 177 static void smtp_io(struct io *, int); 178 static void smtp_data_io(struct io *, int); 179 static void smtp_data_io_done(struct smtp_session *); 180 static void smtp_enter_state(struct smtp_session *, int); 181 static void smtp_reply(struct smtp_session *, char *, ...); 182 static void smtp_command(struct smtp_session *, char *); 183 static int smtp_parse_mail_args(struct smtp_session *, char *); 184 static int smtp_parse_rcpt_args(struct smtp_session *, char *); 185 static void smtp_rfc4954_auth_plain(struct smtp_session *, char *); 186 static void smtp_rfc4954_auth_login(struct smtp_session *, char *); 187 static void smtp_message_end(struct smtp_session *); 188 static int smtp_message_printf(struct smtp_session *, const char *, ...); 189 static void smtp_free(struct smtp_session *, const char *); 190 static const char *smtp_strstate(int); 191 static int smtp_verify_certificate(struct smtp_session *); 192 static uint8_t dsn_notify_str_to_uint8(const char *); 193 static void smtp_auth_failure_pause(struct smtp_session *); 194 static void smtp_auth_failure_resume(int, short, void *); 195 196 static int smtp_tx(struct smtp_session *); 197 static void smtp_tx_free(struct smtp_tx *); 198 199 static void smtp_queue_create_message(struct smtp_session *); 200 static void smtp_queue_open_message(struct smtp_session *); 201 static void smtp_queue_commit(struct smtp_session *); 202 static void smtp_queue_rollback(struct smtp_session *); 203 204 static void smtp_filter_connect(struct smtp_session *, struct sockaddr *); 205 static void smtp_filter_rset(struct smtp_session *); 206 static void smtp_filter_disconnect(struct smtp_session *); 207 static void smtp_filter_tx_begin(struct smtp_session *); 208 static void smtp_filter_tx_commit(struct smtp_session *); 209 static void smtp_filter_tx_rollback(struct smtp_session *); 210 static void smtp_filter_eom(struct smtp_session *); 211 static void smtp_filter_helo(struct smtp_session *); 212 static void smtp_filter_mail(struct smtp_session *); 213 static void smtp_filter_rcpt(struct smtp_session *); 214 static void smtp_filter_data(struct smtp_session *); 215 static void smtp_filter_dataline(struct smtp_session *, const char *); 216 217 static struct { int code; const char *cmd; } commands[] = { 218 { CMD_HELO, "HELO" }, 219 { CMD_EHLO, "EHLO" }, 220 { CMD_STARTTLS, "STARTTLS" }, 221 { CMD_AUTH, "AUTH" }, 222 { CMD_MAIL_FROM, "MAIL FROM" }, 223 { CMD_RCPT_TO, "RCPT TO" }, 224 { CMD_DATA, "DATA" }, 225 { CMD_RSET, "RSET" }, 226 { CMD_QUIT, "QUIT" }, 227 { CMD_HELP, "HELP" }, 228 { CMD_WIZ, "WIZ" }, 229 { CMD_NOOP, "NOOP" }, 230 { -1, NULL }, 231 }; 232 233 static struct tree wait_lka_ptr; 234 static struct tree wait_lka_helo; 235 static struct tree wait_lka_mail; 236 static struct tree wait_lka_rcpt; 237 static struct tree wait_filter; 238 static struct tree wait_filter_data; 239 static struct tree wait_parent_auth; 240 static struct tree wait_queue_msg; 241 static struct tree wait_queue_fd; 242 static struct tree wait_queue_commit; 243 static struct tree wait_ssl_init; 244 static struct tree wait_ssl_verify; 245 246 static void 247 header_default_callback(const struct rfc2822_header *hdr, void *arg) 248 { 249 struct smtp_session *s = arg; 250 struct rfc2822_line *l; 251 252 if (smtp_message_printf(s, "%s:", hdr->name) == -1) 253 return; 254 255 TAILQ_FOREACH(l, &hdr->lines, next) 256 if (smtp_message_printf(s, "%s\n", l->buffer) == -1) 257 return; 258 } 259 260 static void 261 dataline_callback(const char *line, void *arg) 262 { 263 struct smtp_session *s = arg; 264 265 smtp_message_printf(s, "%s\n", line); 266 } 267 268 static void 269 header_bcc_callback(const struct rfc2822_header *hdr, void *arg) 270 { 271 } 272 273 static void 274 header_append_domain_buffer(char *buffer, char *domain, size_t len) 275 { 276 size_t i; 277 int escape, quote, comment, bracket; 278 int has_domain, has_bracket, has_group; 279 int pos_bracket, pos_component, pos_insert; 280 char copy[APPEND_DOMAIN_BUFFER_SIZE]; 281 282 i = 0; 283 escape = quote = comment = bracket = 0; 284 has_domain = has_bracket = has_group = 0; 285 pos_bracket = pos_insert = pos_component = 0; 286 for (i = 0; buffer[i]; ++i) { 287 if (buffer[i] == '(' && !escape && !quote) 288 comment++; 289 if (buffer[i] == '"' && !escape && !comment) 290 quote = !quote; 291 if (buffer[i] == ')' && !escape && !quote && comment) 292 comment--; 293 if (buffer[i] == '\\' && !escape && !comment && !quote) 294 escape = 1; 295 else 296 escape = 0; 297 if (buffer[i] == '<' && !escape && !comment && !quote && !bracket) { 298 bracket++; 299 has_bracket = 1; 300 } 301 if (buffer[i] == '>' && !escape && !comment && !quote && bracket) { 302 bracket--; 303 pos_bracket = i; 304 } 305 if (buffer[i] == '@' && !escape && !comment && !quote) 306 has_domain = 1; 307 if (buffer[i] == ':' && !escape && !comment && !quote) 308 has_group = 1; 309 310 /* update insert point if not in comment and not on a whitespace */ 311 if (!comment && buffer[i] != ')' && !isspace((unsigned char)buffer[i])) 312 pos_component = i; 313 } 314 315 /* parse error, do not attempt to modify */ 316 if (escape || quote || comment || bracket) 317 return; 318 319 /* domain already present, no need to modify */ 320 if (has_domain) 321 return; 322 323 /* address is group, skip */ 324 if (has_group) 325 return; 326 327 /* there's an address between brackets, just append domain */ 328 if (has_bracket) { 329 pos_bracket--; 330 while (isspace((unsigned char)buffer[pos_bracket])) 331 pos_bracket--; 332 if (buffer[pos_bracket] == '<') 333 return; 334 pos_insert = pos_bracket + 1; 335 } 336 else { 337 /* otherwise append address to last component */ 338 pos_insert = pos_component + 1; 339 340 /* empty address */ 341 if (buffer[pos_component] == '\0' || 342 isspace((unsigned char)buffer[pos_component])) 343 return; 344 } 345 346 if (snprintf(copy, sizeof copy, "%.*s@%s%s", 347 (int)pos_insert, buffer, 348 domain, 349 buffer+pos_insert) >= (int)sizeof copy) 350 return; 351 352 memcpy(buffer, copy, len); 353 } 354 355 static void 356 header_domain_append_callback(const struct rfc2822_header *hdr, void *arg) 357 { 358 struct smtp_session *s = arg; 359 struct rfc2822_line *l; 360 size_t i, j; 361 int escape, quote, comment, skip; 362 char buffer[APPEND_DOMAIN_BUFFER_SIZE]; 363 364 if (smtp_message_printf(s, "%s:", hdr->name) == -1) 365 return; 366 367 i = j = 0; 368 escape = quote = comment = skip = 0; 369 memset(buffer, 0, sizeof buffer); 370 371 TAILQ_FOREACH(l, &hdr->lines, next) { 372 for (i = 0; i < strlen(l->buffer); ++i) { 373 if (l->buffer[i] == '(' && !escape && !quote) 374 comment++; 375 if (l->buffer[i] == '"' && !escape && !comment) 376 quote = !quote; 377 if (l->buffer[i] == ')' && !escape && !quote && comment) 378 comment--; 379 if (l->buffer[i] == '\\' && !escape && !comment && !quote) 380 escape = 1; 381 else 382 escape = 0; 383 384 /* found a separator, buffer contains a full address */ 385 if (l->buffer[i] == ',' && !escape && !quote && !comment) { 386 if (!skip && j + strlen(s->listener->hostname) + 1 < sizeof buffer) 387 header_append_domain_buffer(buffer, s->listener->hostname, sizeof buffer); 388 if (smtp_message_printf(s, "%s,", buffer) == -1) 389 return; 390 j = 0; 391 skip = 0; 392 memset(buffer, 0, sizeof buffer); 393 } 394 else { 395 if (skip) { 396 if (smtp_message_printf(s, "%c", 397 l->buffer[i]) == -1) 398 return; 399 } 400 else { 401 buffer[j++] = l->buffer[i]; 402 if (j == sizeof (buffer) - 1) { 403 if (smtp_message_printf(s, "%s", 404 buffer) != -1) 405 return; 406 skip = 1; 407 j = 0; 408 memset(buffer, 0, sizeof buffer); 409 } 410 } 411 } 412 } 413 if (skip) { 414 if (smtp_message_printf(s, "\n") == -1) 415 return; 416 } 417 else { 418 buffer[j++] = '\n'; 419 if (j == sizeof (buffer) - 1) { 420 if (smtp_message_printf(s, "%s", buffer) == -1) 421 return; 422 skip = 1; 423 j = 0; 424 memset(buffer, 0, sizeof buffer); 425 } 426 } 427 } 428 429 /* end of header, if buffer is not empty we'll process it */ 430 if (buffer[0]) { 431 if (j + strlen(s->listener->hostname) + 1 < sizeof buffer) 432 header_append_domain_buffer(buffer, s->listener->hostname, sizeof buffer); 433 smtp_message_printf(s, "%s", buffer); 434 } 435 } 436 437 static void 438 header_address_rewrite_buffer(char *buffer, const char *address, size_t len) 439 { 440 size_t i; 441 int address_len; 442 int escape, quote, comment, bracket; 443 int has_bracket, has_group; 444 int pos_bracket_beg, pos_bracket_end, pos_component_beg, pos_component_end; 445 int insert_beg, insert_end; 446 char copy[APPEND_DOMAIN_BUFFER_SIZE]; 447 448 escape = quote = comment = bracket = 0; 449 has_bracket = has_group = 0; 450 pos_bracket_beg = pos_bracket_end = pos_component_beg = pos_component_end = 0; 451 for (i = 0; buffer[i]; ++i) { 452 if (buffer[i] == '(' && !escape && !quote) 453 comment++; 454 if (buffer[i] == '"' && !escape && !comment) 455 quote = !quote; 456 if (buffer[i] == ')' && !escape && !quote && comment) 457 comment--; 458 if (buffer[i] == '\\' && !escape && !comment && !quote) 459 escape = 1; 460 else 461 escape = 0; 462 if (buffer[i] == '<' && !escape && !comment && !quote && !bracket) { 463 bracket++; 464 has_bracket = 1; 465 pos_bracket_beg = i+1; 466 } 467 if (buffer[i] == '>' && !escape && !comment && !quote && bracket) { 468 bracket--; 469 pos_bracket_end = i; 470 } 471 if (buffer[i] == ':' && !escape && !comment && !quote) 472 has_group = 1; 473 474 /* update insert point if not in comment and not on a whitespace */ 475 if (!comment && buffer[i] != ')' && !isspace((unsigned char)buffer[i])) 476 pos_component_end = i; 477 } 478 479 /* parse error, do not attempt to modify */ 480 if (escape || quote || comment || bracket) 481 return; 482 483 /* address is group, skip */ 484 if (has_group) 485 return; 486 487 /* there's an address between brackets, just replace everything brackets */ 488 if (has_bracket) { 489 insert_beg = pos_bracket_beg; 490 insert_end = pos_bracket_end; 491 } 492 else { 493 if (pos_component_end == 0) 494 pos_component_beg = 0; 495 else { 496 for (pos_component_beg = pos_component_end; pos_component_beg >= 0; --pos_component_beg) 497 if (buffer[pos_component_beg] == ')' || isspace(buffer[pos_component_beg])) 498 break; 499 pos_component_beg += 1; 500 pos_component_end += 1; 501 } 502 insert_beg = pos_component_beg; 503 insert_end = pos_component_end; 504 } 505 506 /* check that masquerade won' t overflow */ 507 address_len = strlen(address); 508 if (strlen(buffer) - (insert_end - insert_beg) + address_len >= len) 509 return; 510 511 (void)strlcpy(copy, buffer, sizeof copy); 512 (void)strlcpy(copy+insert_beg, address, sizeof (copy) - insert_beg); 513 (void)strlcat(copy, buffer+insert_end, sizeof (copy)); 514 memcpy(buffer, copy, len); 515 } 516 517 static void 518 header_masquerade_callback(const struct rfc2822_header *hdr, void *arg) 519 { 520 struct smtp_session *s = arg; 521 struct rfc2822_line *l; 522 size_t i, j; 523 int escape, quote, comment, skip; 524 char buffer[APPEND_DOMAIN_BUFFER_SIZE]; 525 526 if (smtp_message_printf(s, "%s:", hdr->name) == -1) 527 return; 528 529 j = 0; 530 escape = quote = comment = skip = 0; 531 memset(buffer, 0, sizeof buffer); 532 533 TAILQ_FOREACH(l, &hdr->lines, next) { 534 for (i = 0; i < strlen(l->buffer); ++i) { 535 if (l->buffer[i] == '(' && !escape && !quote) 536 comment++; 537 if (l->buffer[i] == '"' && !escape && !comment) 538 quote = !quote; 539 if (l->buffer[i] == ')' && !escape && !quote && comment) 540 comment--; 541 if (l->buffer[i] == '\\' && !escape && !comment && !quote) 542 escape = 1; 543 else 544 escape = 0; 545 546 /* found a separator, buffer contains a full address */ 547 if (l->buffer[i] == ',' && !escape && !quote && !comment) { 548 if (!skip && j + strlen(s->listener->hostname) + 1 < sizeof buffer) { 549 header_append_domain_buffer(buffer, s->listener->hostname, sizeof buffer); 550 header_address_rewrite_buffer(buffer, mailaddr_to_text(&s->tx->evp.sender), 551 sizeof buffer); 552 } 553 if (smtp_message_printf(s, "%s,", buffer) == -1) 554 return; 555 j = 0; 556 skip = 0; 557 memset(buffer, 0, sizeof buffer); 558 } 559 else { 560 if (skip) { 561 if (smtp_message_printf(s, "%c", l->buffer[i]) == -1) 562 return; 563 } 564 else { 565 buffer[j++] = l->buffer[i]; 566 if (j == sizeof (buffer) - 1) { 567 if (smtp_message_printf(s, "%s", buffer) == -1) 568 return; 569 skip = 1; 570 j = 0; 571 memset(buffer, 0, sizeof buffer); 572 } 573 } 574 } 575 } 576 if (skip) { 577 if (smtp_message_printf(s, "\n") == -1) 578 return; 579 } 580 else { 581 buffer[j++] = '\n'; 582 if (j == sizeof (buffer) - 1) { 583 if (smtp_message_printf(s, "%s", buffer) == -1) 584 return; 585 skip = 1; 586 j = 0; 587 memset(buffer, 0, sizeof buffer); 588 } 589 } 590 } 591 592 /* end of header, if buffer is not empty we'll process it */ 593 if (buffer[0]) { 594 if (j + strlen(s->listener->hostname) + 1 < sizeof buffer) { 595 header_append_domain_buffer(buffer, s->listener->hostname, sizeof buffer); 596 header_address_rewrite_buffer(buffer, mailaddr_to_text(&s->tx->evp.sender), 597 sizeof buffer); 598 } 599 smtp_message_printf(s, "%s", buffer); 600 } 601 } 602 603 static void 604 header_missing_callback(const char *header, void *arg) 605 { 606 struct smtp_session *s = arg; 607 608 if (strcasecmp(header, "message-id") == 0) 609 smtp_message_printf(s, "Message-Id: <%016"PRIx64"@%s>\n", 610 generate_uid(), s->listener->hostname); 611 612 if (strcasecmp(header, "date") == 0) 613 smtp_message_printf(s, "Date: %s\n", time_to_text(time(NULL))); 614 } 615 616 static void 617 smtp_session_init(void) 618 { 619 static int init = 0; 620 621 if (!init) { 622 tree_init(&wait_lka_ptr); 623 tree_init(&wait_lka_helo); 624 tree_init(&wait_lka_mail); 625 tree_init(&wait_lka_rcpt); 626 tree_init(&wait_filter); 627 tree_init(&wait_filter_data); 628 tree_init(&wait_parent_auth); 629 tree_init(&wait_queue_msg); 630 tree_init(&wait_queue_fd); 631 tree_init(&wait_queue_commit); 632 tree_init(&wait_ssl_init); 633 tree_init(&wait_ssl_verify); 634 init = 1; 635 } 636 } 637 638 int 639 smtp_session(struct listener *listener, int sock, 640 const struct sockaddr_storage *ss, const char *hostname) 641 { 642 struct smtp_session *s; 643 644 log_debug("debug: smtp: new client on listener: %p", listener); 645 646 smtp_session_init(); 647 648 if ((s = calloc(1, sizeof(*s))) == NULL) 649 return (-1); 650 651 if (iobuf_init(&s->iobuf, LINE_MAX, LINE_MAX) == -1) { 652 free(s); 653 return (-1); 654 } 655 656 s->id = generate_uid(); 657 s->listener = listener; 658 memmove(&s->ss, ss, sizeof(*ss)); 659 io_init(&s->io, sock, s, smtp_io, &s->iobuf); 660 io_set_timeout(&s->io, SMTPD_SESSION_TIMEOUT * 1000); 661 io_set_write(&s->io); 662 663 s->state = STATE_NEW; 664 s->phase = PHASE_INIT; 665 666 (void)strlcpy(s->smtpname, listener->hostname, sizeof(s->smtpname)); 667 668 log_trace(TRACE_SMTP, "smtp: %p: connected to listener %p " 669 "[hostname=%s, port=%d, tag=%s]", s, listener, 670 listener->hostname, ntohs(listener->port), listener->tag); 671 672 /* For local enqueueing, the hostname is already set */ 673 if (hostname) { 674 s->flags |= SF_AUTHENTICATED; 675 /* A bit of a hack */ 676 if (!strcmp(hostname, "localhost")) 677 s->flags |= SF_BOUNCE; 678 (void)strlcpy(s->hostname, hostname, sizeof(s->hostname)); 679 if (smtp_lookup_servername(s)) 680 smtp_connected(s); 681 } else { 682 m_create(p_lka, IMSG_SMTP_DNS_PTR, 0, 0, -1); 683 m_add_id(p_lka, s->id); 684 m_add_sockaddr(p_lka, (struct sockaddr *)&s->ss); 685 m_close(p_lka); 686 tree_xset(&wait_lka_ptr, s->id, s); 687 } 688 689 /* session may have been freed by now */ 690 691 return (0); 692 } 693 694 void 695 smtp_session_imsg(struct mproc *p, struct imsg *imsg) 696 { 697 struct ca_cert_resp_msg *resp_ca_cert; 698 struct ca_vrfy_resp_msg *resp_ca_vrfy; 699 struct smtp_session *s; 700 struct smtp_rcpt *rcpt; 701 void *ssl; 702 char user[LOGIN_NAME_MAX]; 703 struct msg m; 704 const char *line, *helo; 705 uint64_t reqid, evpid; 706 uint32_t msgid; 707 int status, success, dnserror; 708 void *ssl_ctx; 709 710 switch (imsg->hdr.type) { 711 case IMSG_SMTP_DNS_PTR: 712 m_msg(&m, imsg); 713 m_get_id(&m, &reqid); 714 m_get_int(&m, &dnserror); 715 if (dnserror) 716 line = "<unknown>"; 717 else 718 m_get_string(&m, &line); 719 m_end(&m); 720 s = tree_xpop(&wait_lka_ptr, reqid); 721 (void)strlcpy(s->hostname, line, sizeof s->hostname); 722 if (smtp_lookup_servername(s)) 723 smtp_connected(s); 724 return; 725 726 case IMSG_SMTP_CHECK_SENDER: 727 m_msg(&m, imsg); 728 m_get_id(&m, &reqid); 729 m_get_int(&m, &status); 730 m_end(&m); 731 s = tree_xpop(&wait_lka_mail, reqid); 732 switch (status) { 733 case LKA_OK: 734 smtp_queue_create_message(s); 735 736 /* sender check passed, override From callback if masquerading */ 737 if (s->listener->flags & F_MASQUERADE) 738 rfc2822_header_callback(&s->tx->rfc2822_parser, "from", 739 header_masquerade_callback, s); 740 break; 741 742 case LKA_PERMFAIL: 743 smtp_filter_tx_rollback(s); 744 smtp_tx_free(s->tx); 745 smtp_reply(s, "%d %s", 530, "Sender rejected"); 746 io_reload(&s->io); 747 break; 748 case LKA_TEMPFAIL: 749 smtp_filter_tx_rollback(s); 750 smtp_tx_free(s->tx); 751 smtp_reply(s, "421 %s: Temporary Error", 752 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 753 io_reload(&s->io); 754 break; 755 } 756 return; 757 758 case IMSG_SMTP_EXPAND_RCPT: 759 m_msg(&m, imsg); 760 m_get_id(&m, &reqid); 761 m_get_int(&m, &status); 762 m_get_string(&m, &line); 763 m_end(&m); 764 s = tree_xpop(&wait_lka_rcpt, reqid); 765 switch (status) { 766 case LKA_OK: 767 fatalx("unexpected ok"); 768 case LKA_PERMFAIL: 769 smtp_reply(s, "%s", line); 770 break; 771 case LKA_TEMPFAIL: 772 smtp_reply(s, "%s", line); 773 } 774 io_reload(&s->io); 775 return; 776 777 case IMSG_SMTP_LOOKUP_HELO: 778 m_msg(&m, imsg); 779 m_get_id(&m, &reqid); 780 s = tree_xpop(&wait_lka_helo, reqid); 781 m_get_int(&m, &status); 782 if (status == LKA_OK) { 783 m_get_string(&m, &helo); 784 (void)strlcpy(s->smtpname, helo, sizeof(s->smtpname)); 785 } 786 m_end(&m); 787 smtp_connected(s); 788 return; 789 790 case IMSG_SMTP_MESSAGE_CREATE: 791 m_msg(&m, imsg); 792 m_get_id(&m, &reqid); 793 m_get_int(&m, &success); 794 s = tree_xpop(&wait_queue_msg, reqid); 795 if (success) { 796 m_get_msgid(&m, &msgid); 797 s->tx->msgid = msgid; 798 s->tx->evp.id = msgid_to_evpid(msgid); 799 s->tx->rcptcount = 0; 800 s->phase = PHASE_TRANSACTION; 801 smtp_reply(s, "250 %s: Ok", 802 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 803 } else { 804 smtp_filter_tx_rollback(s); 805 smtp_tx_free(s->tx); 806 smtp_reply(s, "421 %s: Temporary Error", 807 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 808 smtp_enter_state(s, STATE_QUIT); 809 } 810 m_end(&m); 811 io_reload(&s->io); 812 return; 813 814 case IMSG_SMTP_MESSAGE_OPEN: 815 m_msg(&m, imsg); 816 m_get_id(&m, &reqid); 817 m_get_int(&m, &success); 818 m_end(&m); 819 820 s = tree_xpop(&wait_queue_fd, reqid); 821 if (!success || imsg->fd == -1) { 822 if (imsg->fd != -1) 823 close(imsg->fd); 824 smtp_reply(s, "421 %s: Temporary Error", 825 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 826 smtp_enter_state(s, STATE_QUIT); 827 io_reload(&s->io); 828 return; 829 } 830 831 log_debug("smtp: %p: fd %d from queue", s, imsg->fd); 832 833 tree_xset(&wait_filter, s->id, s); 834 filter_build_fd_chain(s->id, imsg->fd); 835 return; 836 837 case IMSG_QUEUE_ENVELOPE_SUBMIT: 838 m_msg(&m, imsg); 839 m_get_id(&m, &reqid); 840 m_get_int(&m, &success); 841 s = tree_xget(&wait_lka_rcpt, reqid); 842 if (success) { 843 m_get_evpid(&m, &evpid); 844 s->tx->destcount++; 845 } 846 else 847 s->tx->msgflags |= MF_QUEUE_ENVELOPE_FAIL; 848 m_end(&m); 849 return; 850 851 case IMSG_QUEUE_ENVELOPE_COMMIT: 852 m_msg(&m, imsg); 853 m_get_id(&m, &reqid); 854 m_get_int(&m, &success); 855 m_end(&m); 856 if (!success) 857 fatalx("commit evp failed: not supposed to happen"); 858 s = tree_xpop(&wait_lka_rcpt, reqid); 859 if (s->tx->msgflags & MF_QUEUE_ENVELOPE_FAIL) { 860 /* 861 * If an envelope failed, we can't cancel the last 862 * RCPT only so we must cancel the whole transaction 863 * and close the connection. 864 */ 865 smtp_reply(s, "421 %s: Temporary failure", 866 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 867 smtp_enter_state(s, STATE_QUIT); 868 } 869 else { 870 rcpt = xcalloc(1, sizeof(*rcpt), "smtp_rcpt"); 871 rcpt->destcount = s->tx->destcount; 872 rcpt->maddr = s->tx->evp.rcpt; 873 TAILQ_INSERT_TAIL(&s->tx->rcpts, rcpt, entry); 874 875 s->tx->destcount = 0; 876 s->tx->rcptcount++; 877 smtp_reply(s, "250 %s %s: Recipient ok", 878 esc_code(ESC_STATUS_OK, ESC_DESTINATION_ADDRESS_VALID), 879 esc_description(ESC_DESTINATION_ADDRESS_VALID)); 880 } 881 io_reload(&s->io); 882 return; 883 884 case IMSG_SMTP_MESSAGE_COMMIT: 885 m_msg(&m, imsg); 886 m_get_id(&m, &reqid); 887 m_get_int(&m, &success); 888 m_end(&m); 889 s = tree_xpop(&wait_queue_commit, reqid); 890 if (!success) { 891 smtp_filter_tx_rollback(s); 892 smtp_tx_free(s->tx); 893 smtp_reply(s, "421 %s: Temporary failure", 894 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 895 smtp_enter_state(s, STATE_QUIT); 896 io_reload(&s->io); 897 return; 898 } 899 900 smtp_filter_tx_commit(s); 901 smtp_reply(s, "250 %s: %08x Message accepted for delivery", 902 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS), 903 s->tx->msgid); 904 905 TAILQ_FOREACH(rcpt, &s->tx->rcpts, entry) { 906 log_info("%016"PRIx64" smtp event=message msgid=%08x " 907 "from=<%s%s%s> to=<%s%s%s> size=%zu ndest=%zu proto=%s", 908 s->id, 909 s->tx->msgid, 910 s->tx->evp.sender.user, 911 s->tx->evp.sender.user[0] == '\0' ? "" : "@", 912 s->tx->evp.sender.domain, 913 rcpt->maddr.user, 914 rcpt->maddr.user[0] == '\0' ? "" : "@", 915 rcpt->maddr.domain, 916 s->tx->odatalen, 917 rcpt->destcount, 918 s->flags & SF_EHLO ? "ESMTP" : "SMTP"); 919 } 920 smtp_tx_free(s->tx); 921 s->mailcount++; 922 s->phase = PHASE_SETUP; 923 smtp_enter_state(s, STATE_HELO); 924 io_reload(&s->io); 925 return; 926 927 case IMSG_SMTP_AUTHENTICATE: 928 m_msg(&m, imsg); 929 m_get_id(&m, &reqid); 930 m_get_int(&m, &success); 931 m_end(&m); 932 933 s = tree_xpop(&wait_parent_auth, reqid); 934 strnvis(user, s->username, sizeof user, VIS_WHITE | VIS_SAFE); 935 if (success == LKA_OK) { 936 log_info("%016"PRIx64" smtp " 937 "event=authentication user=%s address=%s " 938 "host=%s result=ok", 939 s->id, user, ss_to_text(&s->ss), s->hostname); 940 s->flags |= SF_AUTHENTICATED; 941 smtp_reply(s, "235 %s: Authentication succeeded", 942 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 943 } 944 else if (success == LKA_PERMFAIL) { 945 log_info("%016"PRIx64" smtp " 946 "event=authentication user=%s address=%s " 947 "host=%s result=permfail", 948 s->id, user, ss_to_text(&s->ss), s->hostname); 949 smtp_auth_failure_pause(s); 950 return; 951 } 952 else if (success == LKA_TEMPFAIL) { 953 log_info("%016"PRIx64" smtp " 954 "event=authentication user=%s address=%s " 955 "host=%s result=tempfail", 956 s->id, user, ss_to_text(&s->ss), s->hostname); 957 smtp_reply(s, "421 %s: Temporary failure", 958 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 959 } 960 else 961 fatalx("bad lka response"); 962 963 smtp_enter_state(s, STATE_HELO); 964 io_reload(&s->io); 965 return; 966 967 case IMSG_SMTP_TLS_INIT: 968 resp_ca_cert = imsg->data; 969 s = tree_xpop(&wait_ssl_init, resp_ca_cert->reqid); 970 971 if (resp_ca_cert->status == CA_FAIL) { 972 log_info("%016"PRIx64" smtp event=closed reason=ca-failure", 973 s->id); 974 smtp_free(s, "CA failure"); 975 return; 976 } 977 978 resp_ca_cert = xmemdup(imsg->data, sizeof *resp_ca_cert, "smtp:ca_cert"); 979 resp_ca_cert->cert = xstrdup((char *)imsg->data + 980 sizeof *resp_ca_cert, "smtp:ca_cert"); 981 ssl_ctx = dict_get(env->sc_ssl_dict, resp_ca_cert->name); 982 ssl = ssl_smtp_init(ssl_ctx, s->listener->flags & F_TLS_VERIFY); 983 io_set_read(&s->io); 984 io_start_tls(&s->io, ssl); 985 986 explicit_bzero(resp_ca_cert->cert, resp_ca_cert->cert_len); 987 free(resp_ca_cert->cert); 988 free(resp_ca_cert); 989 return; 990 991 case IMSG_SMTP_TLS_VERIFY: 992 resp_ca_vrfy = imsg->data; 993 s = tree_xpop(&wait_ssl_verify, resp_ca_vrfy->reqid); 994 995 if (resp_ca_vrfy->status == CA_OK) 996 s->flags |= SF_VERIFIED; 997 else if (s->listener->flags & F_TLS_VERIFY) { 998 log_info("%016"PRIx64" smtp " 999 "event=closed reason=cert-check-failed", 1000 s->id); 1001 smtp_free(s, "SSL certificate check failed"); 1002 return; 1003 } 1004 smtp_io(&s->io, IO_TLSVERIFIED); 1005 io_resume(&s->io, IO_PAUSE_IN); 1006 return; 1007 } 1008 1009 log_warnx("smtp_session_imsg: unexpected %s imsg", 1010 imsg_to_str(imsg->hdr.type)); 1011 fatalx(NULL); 1012 } 1013 1014 void 1015 smtp_filter_response(uint64_t id, int query, int status, uint32_t code, 1016 const char *line) 1017 { 1018 struct smtp_session *s; 1019 struct ca_cert_req_msg req_ca_cert; 1020 1021 s = tree_xpop(&wait_filter, id); 1022 1023 if (status == FILTER_CLOSE) { 1024 code = code ? code : 421; 1025 line = line ? line : "Temporary failure"; 1026 smtp_reply(s, "%d %s", code, line); 1027 smtp_enter_state(s, STATE_QUIT); 1028 io_reload(&s->io); 1029 return; 1030 } 1031 1032 switch (query) { 1033 1034 case QUERY_CONNECT: 1035 if (status != FILTER_OK) { 1036 log_info("%016"PRIx64" smtp " 1037 "event=closed reason=filter-reject", 1038 s->id); 1039 smtp_free(s, "rejected by filter"); 1040 return; 1041 } 1042 1043 if (s->listener->flags & F_SMTPS) { 1044 req_ca_cert.reqid = s->id; 1045 if (s->listener->pki_name[0]) { 1046 (void)strlcpy(req_ca_cert.name, s->listener->pki_name, 1047 sizeof req_ca_cert.name); 1048 req_ca_cert.fallback = 0; 1049 } 1050 else { 1051 (void)strlcpy(req_ca_cert.name, s->smtpname, 1052 sizeof req_ca_cert.name); 1053 req_ca_cert.fallback = 1; 1054 } 1055 m_compose(p_lka, IMSG_SMTP_TLS_INIT, 0, 0, -1, 1056 &req_ca_cert, sizeof(req_ca_cert)); 1057 tree_xset(&wait_ssl_init, s->id, s); 1058 return; 1059 } 1060 smtp_send_banner(s); 1061 return; 1062 1063 case QUERY_HELO: 1064 if (status != FILTER_OK) { 1065 code = code ? code : 530; 1066 line = line ? line : "Hello rejected"; 1067 smtp_reply(s, "%d %s", code, line); 1068 io_reload(&s->io); 1069 return; 1070 } 1071 1072 smtp_enter_state(s, STATE_HELO); 1073 smtp_reply(s, "250%c%s Hello %s [%s], pleased to meet you", 1074 (s->flags & SF_EHLO) ? '-' : ' ', 1075 s->smtpname, 1076 s->helo, 1077 ss_to_text(&s->ss)); 1078 1079 if (s->flags & SF_EHLO) { 1080 smtp_reply(s, "250-8BITMIME"); 1081 smtp_reply(s, "250-ENHANCEDSTATUSCODES"); 1082 smtp_reply(s, "250-SIZE %zu", env->sc_maxsize); 1083 if (ADVERTISE_EXT_DSN(s)) 1084 smtp_reply(s, "250-DSN"); 1085 if (ADVERTISE_TLS(s)) 1086 smtp_reply(s, "250-STARTTLS"); 1087 if (ADVERTISE_AUTH(s)) 1088 smtp_reply(s, "250-AUTH PLAIN LOGIN"); 1089 smtp_reply(s, "250 HELP"); 1090 } 1091 s->phase = PHASE_SETUP; 1092 io_reload(&s->io); 1093 return; 1094 1095 case QUERY_MAIL: 1096 if (status != FILTER_OK) { 1097 smtp_filter_tx_rollback(s); 1098 smtp_tx_free(s->tx); 1099 code = code ? code : 530; 1100 line = line ? line : "Sender rejected"; 1101 smtp_reply(s, "%d %s", code, line); 1102 io_reload(&s->io); 1103 return; 1104 } 1105 1106 /* only check sendertable if defined and user has authenticated */ 1107 if (s->flags & SF_AUTHENTICATED && s->listener->sendertable[0]) { 1108 m_create(p_lka, IMSG_SMTP_CHECK_SENDER, 0, 0, -1); 1109 m_add_id(p_lka, s->id); 1110 m_add_string(p_lka, s->listener->sendertable); 1111 m_add_string(p_lka, s->username); 1112 m_add_mailaddr(p_lka, &s->tx->evp.sender); 1113 m_close(p_lka); 1114 tree_xset(&wait_lka_mail, s->id, s); 1115 } 1116 else 1117 smtp_queue_create_message(s); 1118 return; 1119 1120 case QUERY_RCPT: 1121 if (status != FILTER_OK) { 1122 code = code ? code : 530; 1123 line = line ? line : "Recipient rejected"; 1124 smtp_reply(s, "%d %s", code, line); 1125 io_reload(&s->io); 1126 return; 1127 } 1128 1129 m_create(p_lka, IMSG_SMTP_EXPAND_RCPT, 0, 0, -1); 1130 m_add_id(p_lka, s->id); 1131 m_add_envelope(p_lka, &s->tx->evp); 1132 m_close(p_lka); 1133 tree_xset(&wait_lka_rcpt, s->id, s); 1134 return; 1135 1136 case QUERY_DATA: 1137 if (status != FILTER_OK) { 1138 code = code ? code : 530; 1139 line = line ? line : "Message rejected"; 1140 smtp_reply(s, "%d %s", code, line); 1141 io_reload(&s->io); 1142 return; 1143 } 1144 smtp_queue_open_message(s); 1145 return; 1146 1147 case QUERY_EOM: 1148 if (status != FILTER_OK) { 1149 tree_pop(&wait_filter_data, s->id); 1150 smtp_filter_tx_rollback(s); 1151 smtp_queue_rollback(s); 1152 smtp_tx_free(s->tx); 1153 code = code ? code : 530; 1154 line = line ? line : "Message rejected"; 1155 smtp_reply(s, "%d %s", code, line); 1156 smtp_enter_state(s, STATE_HELO); 1157 io_reload(&s->io); 1158 return; 1159 } 1160 smtp_message_end(s); 1161 return; 1162 1163 default: 1164 log_warn("smtp: bad mfa query type %d", query); 1165 } 1166 } 1167 1168 void 1169 smtp_filter_fd(uint64_t id, int fd) 1170 { 1171 struct smtp_session *s; 1172 X509 *x; 1173 1174 s = tree_xpop(&wait_filter, id); 1175 1176 log_debug("smtp: %p: fd %d from filter", s, fd); 1177 1178 if (fd == -1) { 1179 smtp_reply(s, "421 %s: Temporary Error", 1180 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 1181 smtp_enter_state(s, STATE_QUIT); 1182 io_reload(&s->io); 1183 return; 1184 } 1185 1186 iobuf_init(&s->tx->obuf, 0, 0); 1187 io_set_nonblocking(fd); 1188 io_init(&s->tx->oev, fd, s, smtp_data_io, &s->tx->obuf); 1189 1190 iobuf_fqueue(&s->tx->obuf, "Received: "); 1191 if (!(s->listener->flags & F_MASK_SOURCE)) { 1192 iobuf_fqueue(&s->tx->obuf, "from %s (%s [%s])", 1193 s->helo, 1194 s->hostname, 1195 ss_to_text(&s->ss)); 1196 } 1197 iobuf_fqueue(&s->tx->obuf, "\n\tby %s (%s) with %sSMTP%s%s id %08x", 1198 s->smtpname, 1199 SMTPD_NAME, 1200 s->flags & SF_EHLO ? "E" : "", 1201 s->flags & SF_SECURE ? "S" : "", 1202 s->flags & SF_AUTHENTICATED ? "A" : "", 1203 s->tx->msgid); 1204 1205 if (s->flags & SF_SECURE) { 1206 x = SSL_get_peer_certificate(s->io.ssl); 1207 iobuf_fqueue(&s->tx->obuf, 1208 " (%s:%s:%d:%s)", 1209 SSL_get_version(s->io.ssl), 1210 SSL_get_cipher_name(s->io.ssl), 1211 SSL_get_cipher_bits(s->io.ssl, NULL), 1212 (s->flags & SF_VERIFIED) ? "YES" : (x ? "FAIL" : "NO")); 1213 if (x) 1214 X509_free(x); 1215 1216 if (s->listener->flags & F_RECEIVEDAUTH) { 1217 iobuf_fqueue(&s->tx->obuf, " auth=%s", s->username[0] ? "yes" : "no"); 1218 if (s->username[0]) 1219 iobuf_fqueue(&s->tx->obuf, " user=%s", s->username); 1220 } 1221 } 1222 1223 if (s->tx->rcptcount == 1) { 1224 iobuf_fqueue(&s->tx->obuf, "\n\tfor <%s@%s>", 1225 s->tx->evp.rcpt.user, 1226 s->tx->evp.rcpt.domain); 1227 } 1228 1229 iobuf_fqueue(&s->tx->obuf, ";\n\t%s\n", time_to_text(time(NULL))); 1230 1231 s->tx->odatalen = iobuf_queued(&s->tx->obuf); 1232 1233 io_set_write(&s->tx->oev); 1234 1235 smtp_enter_state(s, STATE_BODY); 1236 smtp_reply(s, "354 Enter mail, end with \".\"" 1237 " on a line by itself"); 1238 1239 tree_xset(&wait_filter_data, s->id, s); 1240 io_reload(&s->io); 1241 } 1242 1243 static void 1244 smtp_io(struct io *io, int evt) 1245 { 1246 struct ca_cert_req_msg req_ca_cert; 1247 struct smtp_session *s = io->arg; 1248 char *line; 1249 size_t len; 1250 X509 *x; 1251 1252 log_trace(TRACE_IO, "smtp: %p: %s %s", s, io_strevent(evt), 1253 io_strio(io)); 1254 1255 switch (evt) { 1256 1257 case IO_TLSREADY: 1258 log_info("%016"PRIx64" smtp event=starttls ciphers=\"%s\"", 1259 s->id, ssl_to_text(s->io.ssl)); 1260 1261 s->flags |= SF_SECURE; 1262 s->phase = PHASE_INIT; 1263 1264 if (smtp_verify_certificate(s)) { 1265 io_pause(&s->io, IO_PAUSE_IN); 1266 break; 1267 } 1268 1269 if (s->listener->flags & F_TLS_VERIFY) { 1270 log_info("%016"PRIx64" smtp " 1271 "event=closed reason=no-client-cert", 1272 s->id); 1273 smtp_free(s, "client did not present certificate"); 1274 return; 1275 } 1276 1277 /* No verification required, cascade */ 1278 1279 case IO_TLSVERIFIED: 1280 x = SSL_get_peer_certificate(s->io.ssl); 1281 if (x) { 1282 log_info("%016"PRIx64" smtp " 1283 "event=client-cert-check result=\"%s\"", 1284 s->id, 1285 (s->flags & SF_VERIFIED) ? "success" : "failure"); 1286 X509_free(x); 1287 } 1288 1289 if (s->listener->flags & F_SMTPS) { 1290 stat_increment("smtp.smtps", 1); 1291 io_set_write(&s->io); 1292 smtp_send_banner(s); 1293 } 1294 else { 1295 stat_increment("smtp.tls", 1); 1296 smtp_enter_state(s, STATE_HELO); 1297 } 1298 break; 1299 1300 case IO_DATAIN: 1301 nextline: 1302 line = iobuf_getline(&s->iobuf, &len); 1303 if ((line == NULL && iobuf_len(&s->iobuf) >= LINE_MAX) || 1304 (line && len >= LINE_MAX)) { 1305 s->flags |= SF_BADINPUT; 1306 smtp_reply(s, "500 %s: Line too long", 1307 esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_STATUS)); 1308 smtp_enter_state(s, STATE_QUIT); 1309 io_set_write(io); 1310 return; 1311 } 1312 1313 /* No complete line received */ 1314 if (line == NULL) { 1315 iobuf_normalize(&s->iobuf); 1316 return; 1317 } 1318 1319 /* Message body */ 1320 if (s->state == STATE_BODY && strcmp(line, ".")) { 1321 smtp_filter_dataline(s, line); 1322 goto nextline; 1323 } 1324 1325 /* Pipelining not supported */ 1326 if (iobuf_len(&s->iobuf)) { 1327 s->flags |= SF_BADINPUT; 1328 smtp_reply(s, "500 %s %s: Pipelining not supported", 1329 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1330 esc_description(ESC_INVALID_COMMAND)); 1331 smtp_enter_state(s, STATE_QUIT); 1332 io_set_write(io); 1333 return; 1334 } 1335 1336 /* End of body */ 1337 if (s->state == STATE_BODY) { 1338 log_trace(TRACE_SMTP, "<<< [EOM]"); 1339 1340 rfc2822_parser_flush(&s->tx->rfc2822_parser); 1341 1342 iobuf_normalize(&s->iobuf); 1343 io_set_write(io); 1344 1345 s->tx->dataeom = 1; 1346 if (iobuf_queued(&s->tx->obuf) == 0) 1347 smtp_data_io_done(s); 1348 return; 1349 } 1350 1351 /* Must be a command */ 1352 (void)strlcpy(s->cmd, line, sizeof s->cmd); 1353 io_set_write(io); 1354 smtp_command(s, line); 1355 iobuf_normalize(&s->iobuf); 1356 break; 1357 1358 case IO_LOWAT: 1359 if (s->state == STATE_QUIT) { 1360 log_info("%016"PRIx64" smtp event=closed reason=quit", 1361 s->id); 1362 smtp_free(s, "done"); 1363 break; 1364 } 1365 1366 /* Wait for the client to start tls */ 1367 if (s->state == STATE_TLS) { 1368 req_ca_cert.reqid = s->id; 1369 1370 if (s->listener->pki_name[0]) { 1371 (void)strlcpy(req_ca_cert.name, s->listener->pki_name, 1372 sizeof req_ca_cert.name); 1373 req_ca_cert.fallback = 0; 1374 } 1375 else { 1376 (void)strlcpy(req_ca_cert.name, s->smtpname, 1377 sizeof req_ca_cert.name); 1378 req_ca_cert.fallback = 1; 1379 } 1380 m_compose(p_lka, IMSG_SMTP_TLS_INIT, 0, 0, -1, 1381 &req_ca_cert, sizeof(req_ca_cert)); 1382 tree_xset(&wait_ssl_init, s->id, s); 1383 break; 1384 } 1385 1386 io_set_read(io); 1387 break; 1388 1389 case IO_TIMEOUT: 1390 log_info("%016"PRIx64" smtp event=closed reason=timeout", 1391 s->id); 1392 smtp_free(s, "timeout"); 1393 break; 1394 1395 case IO_DISCONNECTED: 1396 log_info("%016"PRIx64" smtp event=closed reason=disconnect", 1397 s->id); 1398 smtp_free(s, "disconnected"); 1399 break; 1400 1401 case IO_ERROR: 1402 log_info("%016"PRIx64" smtp event=closed reason=\"io-error: %s\"", 1403 s->id, io->error); 1404 smtp_free(s, "IO error"); 1405 break; 1406 1407 default: 1408 fatalx("smtp_io()"); 1409 } 1410 } 1411 1412 static int 1413 smtp_tx(struct smtp_session *s) 1414 { 1415 struct smtp_tx *tx; 1416 1417 tx = calloc(1, sizeof(*tx)); 1418 if (tx == NULL) 1419 return 0; 1420 1421 TAILQ_INIT(&tx->rcpts); 1422 io_init(&tx->oev, -1, s, NULL, NULL); /* initialise 'sock', but not to 0 */ 1423 1424 s->tx = tx; 1425 tx->session = s; 1426 1427 /* setup the envelope */ 1428 s->tx->evp.ss = s->ss; 1429 (void)strlcpy(s->tx->evp.tag, s->listener->tag, sizeof(s->tx->evp.tag)); 1430 (void)strlcpy(s->tx->evp.smtpname, s->smtpname, sizeof(s->tx->evp.smtpname)); 1431 (void)strlcpy(s->tx->evp.hostname, s->hostname, sizeof s->tx->evp.hostname); 1432 (void)strlcpy(s->tx->evp.helo, s->helo, sizeof s->tx->evp.helo); 1433 1434 if (s->flags & SF_BOUNCE) 1435 s->tx->evp.flags |= EF_BOUNCE; 1436 if (s->flags & SF_AUTHENTICATED) 1437 s->tx->evp.flags |= EF_AUTHENTICATED; 1438 1439 /* Setup parser and callbacks */ 1440 rfc2822_parser_init(&tx->rfc2822_parser); 1441 rfc2822_header_default_callback(&tx->rfc2822_parser, 1442 header_default_callback, s); 1443 rfc2822_header_callback(&tx->rfc2822_parser, "bcc", 1444 header_bcc_callback, s); 1445 rfc2822_header_callback(&tx->rfc2822_parser, "from", 1446 header_domain_append_callback, s); 1447 rfc2822_header_callback(&tx->rfc2822_parser, "to", 1448 header_domain_append_callback, s); 1449 rfc2822_header_callback(&tx->rfc2822_parser, "cc", 1450 header_domain_append_callback, s); 1451 rfc2822_body_callback(&tx->rfc2822_parser, 1452 dataline_callback, s); 1453 1454 if (s->listener->local || s->listener->port == 587) { 1455 rfc2822_missing_header_callback(&tx->rfc2822_parser, "date", 1456 header_missing_callback, s); 1457 rfc2822_missing_header_callback(&tx->rfc2822_parser, "message-id", 1458 header_missing_callback, s); 1459 } 1460 1461 return 1; 1462 } 1463 1464 static void 1465 smtp_tx_free(struct smtp_tx *tx) 1466 { 1467 struct smtp_rcpt *rcpt; 1468 1469 rfc2822_parser_release(&tx->rfc2822_parser); 1470 1471 while ((rcpt = TAILQ_FIRST(&tx->rcpts))) { 1472 TAILQ_REMOVE(&tx->rcpts, rcpt, entry); 1473 free(rcpt); 1474 } 1475 1476 tx->session->tx = NULL; 1477 1478 free(tx); 1479 } 1480 1481 static void 1482 smtp_data_io(struct io *io, int evt) 1483 { 1484 struct smtp_session *s = io->arg; 1485 1486 log_trace(TRACE_IO, "smtp: %p (data): %s %s", s, io_strevent(evt), 1487 io_strio(io)); 1488 1489 switch (evt) { 1490 case IO_TIMEOUT: 1491 case IO_DISCONNECTED: 1492 case IO_ERROR: 1493 log_debug("debug: smtp: %p: io error on mfa", s); 1494 io_clear(&s->tx->oev); 1495 iobuf_clear(&s->tx->obuf); 1496 s->tx->msgflags |= MF_ERROR_IO; 1497 if (s->io.flags & IO_PAUSE_IN) { 1498 log_debug("debug: smtp: %p: resuming session after mfa error", s); 1499 io_resume(&s->io, IO_PAUSE_IN); 1500 } 1501 break; 1502 1503 case IO_LOWAT: 1504 if (s->tx->dataeom && iobuf_queued(&s->tx->obuf) == 0) { 1505 smtp_data_io_done(s); 1506 } else if (s->io.flags & IO_PAUSE_IN) { 1507 log_debug("debug: smtp: %p: filter congestion over: resuming session", s); 1508 io_resume(&s->io, IO_PAUSE_IN); 1509 } 1510 break; 1511 1512 default: 1513 fatalx("smtp_data_io()"); 1514 } 1515 } 1516 1517 static void 1518 smtp_data_io_done(struct smtp_session *s) 1519 { 1520 log_debug("debug: smtp: %p: data io done (%zu bytes)", s, s->tx->odatalen); 1521 io_clear(&s->tx->oev); 1522 iobuf_clear(&s->tx->obuf); 1523 1524 if (s->tx->msgflags & MF_ERROR) { 1525 1526 tree_pop(&wait_filter_data, s->id); 1527 1528 smtp_filter_tx_rollback(s); 1529 smtp_queue_rollback(s); 1530 1531 if (s->tx->msgflags & MF_ERROR_SIZE) 1532 smtp_reply(s, "554 Message too big"); 1533 else if (s->tx->msgflags & MF_ERROR_LOOP) 1534 smtp_reply(s, "500 %s %s: Loop detected", 1535 esc_code(ESC_STATUS_PERMFAIL, ESC_ROUTING_LOOP_DETECTED), 1536 esc_description(ESC_ROUTING_LOOP_DETECTED)); 1537 else if (s->tx->msgflags & MF_ERROR_RESOURCES) 1538 smtp_reply(s, "421 %s: Temporary Error", 1539 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 1540 else if (s->tx->msgflags & MF_ERROR_MALFORMED) 1541 smtp_reply(s, "550 %s %s: Message is not RFC 2822 compliant", 1542 esc_code(ESC_STATUS_PERMFAIL, 1543 ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED), 1544 esc_description(ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED)); 1545 else if (s->tx->msgflags) 1546 smtp_reply(s, "421 Internal server error"); 1547 smtp_tx_free(s->tx); 1548 smtp_enter_state(s, STATE_HELO); 1549 io_reload(&s->io); 1550 } 1551 else { 1552 smtp_filter_eom(s); 1553 } 1554 } 1555 1556 static void 1557 smtp_command(struct smtp_session *s, char *line) 1558 { 1559 char *args, *eom, *method; 1560 int cmd, i; 1561 1562 log_trace(TRACE_SMTP, "smtp: %p: <<< %s", s, line); 1563 1564 /* 1565 * These states are special. 1566 */ 1567 if (s->state == STATE_AUTH_INIT) { 1568 smtp_rfc4954_auth_plain(s, line); 1569 return; 1570 } 1571 if (s->state == STATE_AUTH_USERNAME || s->state == STATE_AUTH_PASSWORD) { 1572 smtp_rfc4954_auth_login(s, line); 1573 return; 1574 } 1575 1576 /* 1577 * Unlike other commands, "mail from" and "rcpt to" contain a 1578 * space in the command name. 1579 */ 1580 if (strncasecmp("mail from:", line, 10) == 0 || 1581 strncasecmp("rcpt to:", line, 8) == 0) 1582 args = strchr(line, ':'); 1583 else 1584 args = strchr(line, ' '); 1585 1586 if (args) { 1587 *args++ = '\0'; 1588 while (isspace((unsigned char)*args)) 1589 args++; 1590 } 1591 1592 cmd = -1; 1593 for (i = 0; commands[i].code != -1; i++) 1594 if (!strcasecmp(line, commands[i].cmd)) { 1595 cmd = commands[i].code; 1596 break; 1597 } 1598 1599 switch (cmd) { 1600 /* 1601 * INIT 1602 */ 1603 case CMD_HELO: 1604 case CMD_EHLO: 1605 if (s->phase != PHASE_INIT) { 1606 smtp_reply(s, "503 %s %s: Already identified", 1607 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1608 esc_description(ESC_INVALID_COMMAND)); 1609 break; 1610 } 1611 1612 if (args == NULL) { 1613 smtp_reply(s, "501 %s %s: %s requires domain name", 1614 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1615 esc_description(ESC_INVALID_COMMAND), 1616 (cmd == CMD_HELO) ? "HELO" : "EHLO"); 1617 1618 break; 1619 } 1620 1621 if (!valid_domainpart(args)) { 1622 smtp_reply(s, "501 %s %s: Invalid domain name", 1623 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1624 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1625 break; 1626 } 1627 (void)strlcpy(s->helo, args, sizeof(s->helo)); 1628 s->flags &= SF_SECURE | SF_AUTHENTICATED | SF_VERIFIED | SF_FILTERCONN; 1629 if (cmd == CMD_EHLO) { 1630 s->flags |= SF_EHLO; 1631 s->flags |= SF_8BITMIME; 1632 } 1633 1634 smtp_filter_helo(s); 1635 break; 1636 /* 1637 * SETUP 1638 */ 1639 case CMD_STARTTLS: 1640 if (s->phase != PHASE_SETUP) { 1641 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1642 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1643 esc_description(ESC_INVALID_COMMAND)); 1644 break; 1645 } 1646 1647 if (!(s->listener->flags & F_STARTTLS)) { 1648 smtp_reply(s, "503 %s %s: Command not supported", 1649 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1650 esc_description(ESC_INVALID_COMMAND)); 1651 break; 1652 } 1653 1654 if (s->flags & SF_SECURE) { 1655 smtp_reply(s, "503 %s %s: Channel already secured", 1656 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1657 esc_description(ESC_INVALID_COMMAND)); 1658 break; 1659 } 1660 if (args != NULL) { 1661 smtp_reply(s, "501 %s %s: No parameters allowed", 1662 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1663 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1664 break; 1665 } 1666 smtp_reply(s, "220 %s: Ready to start TLS", 1667 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 1668 smtp_enter_state(s, STATE_TLS); 1669 break; 1670 1671 case CMD_AUTH: 1672 if (s->phase != PHASE_SETUP) { 1673 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1674 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1675 esc_description(ESC_INVALID_COMMAND)); 1676 break; 1677 } 1678 1679 if (s->flags & SF_AUTHENTICATED) { 1680 smtp_reply(s, "503 %s %s: Already authenticated", 1681 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1682 esc_description(ESC_INVALID_COMMAND)); 1683 break; 1684 } 1685 1686 if (!ADVERTISE_AUTH(s)) { 1687 smtp_reply(s, "503 %s %s: Command not supported", 1688 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1689 esc_description(ESC_INVALID_COMMAND)); 1690 break; 1691 } 1692 1693 if (args == NULL) { 1694 smtp_reply(s, "501 %s %s: No parameters given", 1695 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1696 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1697 break; 1698 } 1699 1700 method = args; 1701 eom = strchr(args, ' '); 1702 if (eom == NULL) 1703 eom = strchr(args, '\t'); 1704 if (eom != NULL) 1705 *eom++ = '\0'; 1706 if (strcasecmp(method, "PLAIN") == 0) 1707 smtp_rfc4954_auth_plain(s, eom); 1708 else if (strcasecmp(method, "LOGIN") == 0) 1709 smtp_rfc4954_auth_login(s, eom); 1710 else 1711 smtp_reply(s, "504 %s %s: AUTH method \"%s\" not supported", 1712 esc_code(ESC_STATUS_PERMFAIL, ESC_SECURITY_FEATURES_NOT_SUPPORTED), 1713 esc_description(ESC_SECURITY_FEATURES_NOT_SUPPORTED), 1714 method); 1715 break; 1716 1717 case CMD_MAIL_FROM: 1718 if (s->phase != PHASE_SETUP) { 1719 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1720 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1721 esc_description(ESC_INVALID_COMMAND)); 1722 1723 break; 1724 } 1725 1726 if (s->listener->flags & F_STARTTLS_REQUIRE && 1727 !(s->flags & SF_SECURE)) { 1728 smtp_reply(s, 1729 "530 %s %s: Must issue a STARTTLS command first", 1730 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1731 esc_description(ESC_INVALID_COMMAND)); 1732 break; 1733 } 1734 1735 if (s->listener->flags & F_AUTH_REQUIRE && 1736 !(s->flags & SF_AUTHENTICATED)) { 1737 smtp_reply(s, 1738 "530 %s %s: Must issue an AUTH command first", 1739 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1740 esc_description(ESC_INVALID_COMMAND)); 1741 break; 1742 } 1743 1744 if (s->mailcount >= env->sc_session_max_mails) { 1745 /* we can pretend we had too many recipients */ 1746 smtp_reply(s, "452 %s %s: Too many messages sent", 1747 esc_code(ESC_STATUS_TEMPFAIL, ESC_TOO_MANY_RECIPIENTS), 1748 esc_description(ESC_TOO_MANY_RECIPIENTS)); 1749 break; 1750 } 1751 1752 if (!smtp_tx(s)) { 1753 smtp_reply(s, "421 %s: Temporary Error", 1754 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 1755 smtp_enter_state(s, STATE_QUIT); 1756 break; 1757 } 1758 1759 if (smtp_mailaddr(&s->tx->evp.sender, args, 1, &args, 1760 s->smtpname) == 0) { 1761 smtp_tx_free(s->tx); 1762 smtp_reply(s, "553 %s: Sender address syntax error", 1763 esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_ADDRESS_STATUS)); 1764 break; 1765 } 1766 if (args && smtp_parse_mail_args(s, args) == -1) { 1767 smtp_tx_free(s->tx); 1768 break; 1769 } 1770 1771 smtp_filter_tx_begin(s); 1772 smtp_filter_mail(s); 1773 break; 1774 /* 1775 * TRANSACTION 1776 */ 1777 case CMD_RCPT_TO: 1778 if (s->phase != PHASE_TRANSACTION) { 1779 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1780 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1781 esc_description(ESC_INVALID_COMMAND)); 1782 break; 1783 } 1784 1785 if (s->tx->rcptcount >= env->sc_session_max_rcpt) { 1786 smtp_reply(s, "451 %s %s: Too many recipients", 1787 esc_code(ESC_STATUS_TEMPFAIL, ESC_TOO_MANY_RECIPIENTS), 1788 esc_description(ESC_TOO_MANY_RECIPIENTS)); 1789 break; 1790 } 1791 1792 if (smtp_mailaddr(&s->tx->evp.rcpt, args, 0, &args, 1793 s->smtpname) == 0) { 1794 smtp_reply(s, 1795 "501 %s: Recipient address syntax error", 1796 esc_code(ESC_STATUS_PERMFAIL, ESC_BAD_DESTINATION_MAILBOX_ADDRESS_SYNTAX)); 1797 break; 1798 } 1799 if (args && smtp_parse_rcpt_args(s, args) == -1) 1800 break; 1801 1802 smtp_filter_rcpt(s); 1803 break; 1804 1805 case CMD_RSET: 1806 if (s->phase != PHASE_TRANSACTION && s->phase != PHASE_SETUP) { 1807 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1808 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1809 esc_description(ESC_INVALID_COMMAND)); 1810 break; 1811 } 1812 1813 if (s->tx) { 1814 smtp_filter_tx_rollback(s); 1815 if (s->tx->msgid) 1816 smtp_queue_rollback(s); 1817 smtp_tx_free(s->tx); 1818 } 1819 1820 smtp_filter_rset(s); 1821 1822 s->phase = PHASE_SETUP; 1823 smtp_reply(s, "250 %s: Reset state", 1824 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 1825 break; 1826 1827 case CMD_DATA: 1828 if (s->phase != PHASE_TRANSACTION) { 1829 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1830 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1831 esc_description(ESC_INVALID_COMMAND)); 1832 break; 1833 } 1834 if (s->tx->rcptcount == 0) { 1835 smtp_reply(s, "503 %s %s: No recipient specified", 1836 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1837 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1838 break; 1839 } 1840 1841 smtp_filter_data(s); 1842 break; 1843 /* 1844 * ANY 1845 */ 1846 case CMD_QUIT: 1847 smtp_reply(s, "221 %s: Bye", 1848 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 1849 smtp_enter_state(s, STATE_QUIT); 1850 break; 1851 1852 case CMD_NOOP: 1853 smtp_reply(s, "250 %s: Ok", 1854 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 1855 break; 1856 1857 case CMD_HELP: 1858 smtp_reply(s, "214- This is " SMTPD_NAME); 1859 smtp_reply(s, "214- To report bugs in the implementation, " 1860 "please contact bugs@openbsd.org"); 1861 smtp_reply(s, "214- with full details"); 1862 smtp_reply(s, "214 %s: End of HELP info", 1863 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 1864 break; 1865 1866 case CMD_WIZ: 1867 smtp_reply(s, "500 %s %s: this feature is not supported yet ;-)", 1868 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1869 esc_description(ESC_INVALID_COMMAND)); 1870 break; 1871 1872 default: 1873 smtp_reply(s, "500 %s %s: Command unrecognized", 1874 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1875 esc_description(ESC_INVALID_COMMAND)); 1876 break; 1877 } 1878 } 1879 1880 static void 1881 smtp_rfc4954_auth_plain(struct smtp_session *s, char *arg) 1882 { 1883 char buf[1024], *user, *pass; 1884 int len; 1885 1886 switch (s->state) { 1887 case STATE_HELO: 1888 if (arg == NULL) { 1889 smtp_enter_state(s, STATE_AUTH_INIT); 1890 smtp_reply(s, "334 "); 1891 return; 1892 } 1893 smtp_enter_state(s, STATE_AUTH_INIT); 1894 /* FALLTHROUGH */ 1895 1896 case STATE_AUTH_INIT: 1897 /* String is not NUL terminated, leave room. */ 1898 if ((len = base64_decode(arg, (unsigned char *)buf, 1899 sizeof(buf) - 1)) == -1) 1900 goto abort; 1901 /* buf is a byte string, NUL terminate. */ 1902 buf[len] = '\0'; 1903 1904 /* 1905 * Skip "foo" in "foo\0user\0pass", if present. 1906 */ 1907 user = memchr(buf, '\0', len); 1908 if (user == NULL || user >= buf + len - 2) 1909 goto abort; 1910 user++; /* skip NUL */ 1911 if (strlcpy(s->username, user, sizeof(s->username)) 1912 >= sizeof(s->username)) 1913 goto abort; 1914 1915 pass = memchr(user, '\0', len - (user - buf)); 1916 if (pass == NULL || pass >= buf + len - 2) 1917 goto abort; 1918 pass++; /* skip NUL */ 1919 1920 m_create(p_lka, IMSG_SMTP_AUTHENTICATE, 0, 0, -1); 1921 m_add_id(p_lka, s->id); 1922 m_add_string(p_lka, s->listener->authtable); 1923 m_add_string(p_lka, user); 1924 m_add_string(p_lka, pass); 1925 m_close(p_lka); 1926 tree_xset(&wait_parent_auth, s->id, s); 1927 return; 1928 1929 default: 1930 fatal("smtp_rfc4954_auth_plain: unknown state"); 1931 } 1932 1933 abort: 1934 smtp_reply(s, "501 %s %s: Syntax error", 1935 esc_code(ESC_STATUS_PERMFAIL, ESC_SYNTAX_ERROR), 1936 esc_description(ESC_SYNTAX_ERROR)); 1937 smtp_enter_state(s, STATE_HELO); 1938 } 1939 1940 static void 1941 smtp_rfc4954_auth_login(struct smtp_session *s, char *arg) 1942 { 1943 char buf[LINE_MAX]; 1944 1945 switch (s->state) { 1946 case STATE_HELO: 1947 smtp_enter_state(s, STATE_AUTH_USERNAME); 1948 smtp_reply(s, "334 VXNlcm5hbWU6"); 1949 return; 1950 1951 case STATE_AUTH_USERNAME: 1952 memset(s->username, 0, sizeof(s->username)); 1953 if (base64_decode(arg, (unsigned char *)s->username, 1954 sizeof(s->username) - 1) == -1) 1955 goto abort; 1956 1957 smtp_enter_state(s, STATE_AUTH_PASSWORD); 1958 smtp_reply(s, "334 UGFzc3dvcmQ6"); 1959 return; 1960 1961 case STATE_AUTH_PASSWORD: 1962 memset(buf, 0, sizeof(buf)); 1963 if (base64_decode(arg, (unsigned char *)buf, 1964 sizeof(buf)-1) == -1) 1965 goto abort; 1966 1967 m_create(p_lka, IMSG_SMTP_AUTHENTICATE, 0, 0, -1); 1968 m_add_id(p_lka, s->id); 1969 m_add_string(p_lka, s->listener->authtable); 1970 m_add_string(p_lka, s->username); 1971 m_add_string(p_lka, buf); 1972 m_close(p_lka); 1973 tree_xset(&wait_parent_auth, s->id, s); 1974 return; 1975 1976 default: 1977 fatal("smtp_rfc4954_auth_login: unknown state"); 1978 } 1979 1980 abort: 1981 smtp_reply(s, "501 %s %s: Syntax error", 1982 esc_code(ESC_STATUS_PERMFAIL, ESC_SYNTAX_ERROR), 1983 esc_description(ESC_SYNTAX_ERROR)); 1984 smtp_enter_state(s, STATE_HELO); 1985 } 1986 1987 static uint8_t 1988 dsn_notify_str_to_uint8(const char *arg) 1989 { 1990 if (strcasecmp(arg, "SUCCESS") == 0) 1991 return DSN_SUCCESS; 1992 else if (strcasecmp(arg, "FAILURE") == 0) 1993 return DSN_FAILURE; 1994 else if (strcasecmp(arg, "DELAY") == 0) 1995 return DSN_DELAY; 1996 else if (strcasecmp(arg, "NEVER") == 0) 1997 return DSN_NEVER; 1998 1999 return (0); 2000 } 2001 2002 static int 2003 smtp_parse_rcpt_args(struct smtp_session *s, char *args) 2004 { 2005 char *b, *p; 2006 uint8_t flag; 2007 2008 while ((b = strsep(&args, " "))) { 2009 if (*b == '\0') 2010 continue; 2011 2012 if (ADVERTISE_EXT_DSN(s) && strncasecmp(b, "NOTIFY=", 7) == 0) { 2013 b += 7; 2014 while ((p = strsep(&b, ","))) { 2015 if (*p == '\0') 2016 continue; 2017 2018 if ((flag = dsn_notify_str_to_uint8(p)) == 0) 2019 continue; 2020 2021 s->tx->evp.dsn_notify |= flag; 2022 } 2023 if (s->tx->evp.dsn_notify & DSN_NEVER && 2024 s->tx->evp.dsn_notify & (DSN_SUCCESS | DSN_FAILURE | 2025 DSN_DELAY)) { 2026 smtp_reply(s, 2027 "553 NOTIFY option NEVER cannot be \ 2028 combined with other options"); 2029 return (-1); 2030 } 2031 } else if (ADVERTISE_EXT_DSN(s) && strncasecmp(b, "ORCPT=", 6) == 0) { 2032 b += 6; 2033 if (!text_to_mailaddr(&s->tx->evp.dsn_orcpt, b)) { 2034 smtp_reply(s, "553 ORCPT address syntax error"); 2035 return (-1); 2036 } 2037 } else { 2038 smtp_reply(s, "503 Unsupported option %s", b); 2039 return (-1); 2040 } 2041 } 2042 2043 return (0); 2044 } 2045 2046 static int 2047 smtp_parse_mail_args(struct smtp_session *s, char *args) 2048 { 2049 char *b; 2050 2051 while ((b = strsep(&args, " "))) { 2052 if (*b == '\0') 2053 continue; 2054 2055 if (strncasecmp(b, "AUTH=", 5) == 0) 2056 log_debug("debug: smtp: AUTH in MAIL FROM command"); 2057 else if (strncasecmp(b, "SIZE=", 5) == 0) 2058 log_debug("debug: smtp: SIZE in MAIL FROM command"); 2059 else if (strcasecmp(b, "BODY=7BIT") == 0) 2060 /* XXX only for this transaction */ 2061 s->flags &= ~SF_8BITMIME; 2062 else if (strcasecmp(b, "BODY=8BITMIME") == 0) 2063 ; 2064 else if (ADVERTISE_EXT_DSN(s) && strncasecmp(b, "RET=", 4) == 0) { 2065 b += 4; 2066 if (strcasecmp(b, "HDRS") == 0) 2067 s->tx->evp.dsn_ret = DSN_RETHDRS; 2068 else if (strcasecmp(b, "FULL") == 0) 2069 s->tx->evp.dsn_ret = DSN_RETFULL; 2070 } else if (ADVERTISE_EXT_DSN(s) && strncasecmp(b, "ENVID=", 6) == 0) { 2071 b += 6; 2072 if (strlcpy(s->tx->evp.dsn_envid, b, sizeof(s->tx->evp.dsn_envid)) 2073 >= sizeof(s->tx->evp.dsn_envid)) { 2074 smtp_reply(s, "503 %s %s: option too large, truncated: %s", 2075 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 2076 esc_description(ESC_INVALID_COMMAND_ARGUMENTS), b); 2077 return (-1); 2078 } 2079 } else { 2080 smtp_reply(s, "503 %s %s: Unsupported option %s", 2081 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 2082 esc_description(ESC_INVALID_COMMAND_ARGUMENTS), b); 2083 return (-1); 2084 } 2085 } 2086 2087 return (0); 2088 } 2089 2090 static int 2091 smtp_lookup_servername(struct smtp_session *s) 2092 { 2093 struct sockaddr *sa; 2094 socklen_t sa_len; 2095 struct sockaddr_storage ss; 2096 2097 if (s->listener->hostnametable[0]) { 2098 sa_len = sizeof(ss); 2099 sa = (struct sockaddr *)&ss; 2100 if (getsockname(s->io.sock, sa, &sa_len) == -1) { 2101 log_warn("warn: getsockname()"); 2102 } 2103 else { 2104 m_create(p_lka, IMSG_SMTP_LOOKUP_HELO, 0, 0, -1); 2105 m_add_id(p_lka, s->id); 2106 m_add_string(p_lka, s->listener->hostnametable); 2107 m_add_sockaddr(p_lka, sa); 2108 m_close(p_lka); 2109 tree_xset(&wait_lka_helo, s->id, s); 2110 return 0; 2111 } 2112 } 2113 return 1; 2114 } 2115 2116 static void 2117 smtp_connected(struct smtp_session *s) 2118 { 2119 struct sockaddr_storage ss; 2120 socklen_t sl; 2121 2122 smtp_enter_state(s, STATE_CONNECTED); 2123 2124 log_info("%016"PRIx64" smtp event=connected address=%s host=%s", 2125 s->id, ss_to_text(&s->ss), s->hostname); 2126 2127 sl = sizeof(ss); 2128 if (getsockname(s->io.sock, (struct sockaddr*)&ss, &sl) == -1) { 2129 smtp_free(s, strerror(errno)); 2130 return; 2131 } 2132 2133 s->flags |= SF_FILTERCONN; 2134 smtp_filter_connect(s, (struct sockaddr *)&ss); 2135 } 2136 2137 static void 2138 smtp_send_banner(struct smtp_session *s) 2139 { 2140 smtp_reply(s, "220 %s ESMTP %s", s->smtpname, SMTPD_NAME); 2141 io_reload(&s->io); 2142 } 2143 2144 void 2145 smtp_enter_state(struct smtp_session *s, int newstate) 2146 { 2147 log_trace(TRACE_SMTP, "smtp: %p: %s -> %s", s, 2148 smtp_strstate(s->state), 2149 smtp_strstate(newstate)); 2150 2151 s->state = newstate; 2152 } 2153 2154 static void 2155 smtp_message_end(struct smtp_session *s) 2156 { 2157 log_debug("debug: %p: end of message, msgflags=0x%04x", s, s->tx->msgflags); 2158 2159 tree_xpop(&wait_filter_data, s->id); 2160 2161 s->phase = PHASE_SETUP; 2162 2163 if (s->tx->msgflags & MF_ERROR) { 2164 smtp_filter_tx_rollback(s); 2165 smtp_queue_rollback(s); 2166 if (s->tx->msgflags & MF_ERROR_SIZE) 2167 smtp_reply(s, "554 %s %s: Transaction failed, message too big", 2168 esc_code(ESC_STATUS_PERMFAIL, ESC_MESSAGE_TOO_BIG_FOR_SYSTEM), 2169 esc_description(ESC_MESSAGE_TOO_BIG_FOR_SYSTEM)); 2170 else 2171 smtp_reply(s, "%d Message rejected", s->tx->msgcode); 2172 smtp_tx_free(s->tx); 2173 smtp_enter_state(s, STATE_HELO); 2174 return; 2175 } 2176 2177 smtp_queue_commit(s); 2178 } 2179 2180 static int 2181 smtp_message_printf(struct smtp_session *s, const char *fmt, ...) 2182 { 2183 va_list ap; 2184 int len; 2185 2186 if (s->tx->msgflags & MF_ERROR) 2187 return -1; 2188 2189 va_start(ap, fmt); 2190 len = iobuf_vfqueue(&s->tx->obuf, fmt, ap); 2191 va_end(ap); 2192 2193 if (len < 0) { 2194 log_warn("smtp-in: session %016"PRIx64": vfprintf", s->id); 2195 s->tx->msgflags |= MF_ERROR_IO; 2196 } 2197 else 2198 s->tx->odatalen += len; 2199 2200 return len; 2201 } 2202 2203 static void 2204 smtp_reply(struct smtp_session *s, char *fmt, ...) 2205 { 2206 va_list ap; 2207 int n; 2208 char buf[LINE_MAX], tmp[LINE_MAX]; 2209 2210 va_start(ap, fmt); 2211 n = vsnprintf(buf, sizeof buf, fmt, ap); 2212 va_end(ap); 2213 if (n == -1 || n >= LINE_MAX) 2214 fatalx("smtp_reply: line too long"); 2215 if (n < 4) 2216 fatalx("smtp_reply: response too short"); 2217 2218 log_trace(TRACE_SMTP, "smtp: %p: >>> %s", s, buf); 2219 2220 iobuf_xfqueue(&s->iobuf, "smtp_reply", "%s\r\n", buf); 2221 2222 switch (buf[0]) { 2223 case '5': 2224 case '4': 2225 if (s->flags & SF_BADINPUT) { 2226 log_info("%016"PRIx64" smtp " 2227 "event=bad-input result=\"%.*s\"", 2228 s->id, n, buf); 2229 } 2230 else if (s->state == STATE_AUTH_INIT) { 2231 log_info("smtp-in: Failed command on session %016"PRIx64 2232 ": \"AUTH PLAIN (...)\" => %.*s", s->id, n, buf); 2233 } 2234 else if (s->state == STATE_AUTH_USERNAME) { 2235 log_info("smtp-in: Failed command on session %016"PRIx64 2236 ": \"AUTH LOGIN (username)\" => %.*s", s->id, n, buf); 2237 } 2238 else if (s->state == STATE_AUTH_PASSWORD) { 2239 log_info("smtp-in: Failed command on session %016"PRIx64 2240 ": \"AUTH LOGIN (password)\" => %.*s", s->id, n, buf); 2241 } 2242 else { 2243 strnvis(tmp, s->cmd, sizeof tmp, VIS_SAFE | VIS_CSTYLE); 2244 log_info("%016"PRIx64" smtp " 2245 "event=failed-command command=\"%s\" result=\"%.*s\"", 2246 s->id, tmp, n, buf); 2247 } 2248 break; 2249 } 2250 } 2251 2252 static void 2253 smtp_free(struct smtp_session *s, const char * reason) 2254 { 2255 log_debug("debug: smtp: %p: deleting session: %s", s, reason); 2256 2257 tree_pop(&wait_filter_data, s->id); 2258 2259 if (s->tx) { 2260 if (s->tx->msgid) { 2261 smtp_queue_rollback(s); 2262 io_clear(&s->tx->oev); 2263 iobuf_clear(&s->tx->obuf); 2264 } 2265 smtp_filter_tx_rollback(s); 2266 smtp_tx_free(s->tx); 2267 } 2268 2269 if (s->flags & SF_FILTERCONN) 2270 smtp_filter_disconnect(s); 2271 2272 if (s->flags & SF_SECURE && s->listener->flags & F_SMTPS) 2273 stat_decrement("smtp.smtps", 1); 2274 if (s->flags & SF_SECURE && s->listener->flags & F_STARTTLS) 2275 stat_decrement("smtp.tls", 1); 2276 2277 io_clear(&s->io); 2278 iobuf_clear(&s->iobuf); 2279 free(s); 2280 2281 smtp_collect(); 2282 } 2283 2284 static int 2285 smtp_mailaddr(struct mailaddr *maddr, char *line, int mailfrom, char **args, 2286 const char *domain) 2287 { 2288 char *p, *e; 2289 2290 if (line == NULL) 2291 return (0); 2292 2293 if (*line != '<') 2294 return (0); 2295 2296 e = strchr(line, '>'); 2297 if (e == NULL) 2298 return (0); 2299 *e++ = '\0'; 2300 while (*e == ' ') 2301 e++; 2302 *args = e; 2303 2304 if (!text_to_mailaddr(maddr, line + 1)) 2305 return (0); 2306 2307 p = strchr(maddr->user, ':'); 2308 if (p != NULL) { 2309 p++; 2310 memmove(maddr->user, p, strlen(p) + 1); 2311 } 2312 2313 if (!valid_localpart(maddr->user) || 2314 !valid_domainpart(maddr->domain)) { 2315 /* accept empty return-path in MAIL FROM, required for bounces */ 2316 if (mailfrom && maddr->user[0] == '\0' && maddr->domain[0] == '\0') 2317 return (1); 2318 2319 /* no user-part, reject */ 2320 if (maddr->user[0] == '\0') 2321 return (0); 2322 2323 /* no domain, local user */ 2324 if (maddr->domain[0] == '\0') { 2325 (void)strlcpy(maddr->domain, domain, 2326 sizeof(maddr->domain)); 2327 return (1); 2328 } 2329 return (0); 2330 } 2331 2332 return (1); 2333 } 2334 2335 static int 2336 smtp_verify_certificate(struct smtp_session *s) 2337 { 2338 #define MAX_CERTS 16 2339 #define MAX_CERT_LEN (MAX_IMSGSIZE - (IMSG_HEADER_SIZE + sizeof(req_ca_vrfy))) 2340 struct ca_vrfy_req_msg req_ca_vrfy; 2341 struct iovec iov[2]; 2342 X509 *x; 2343 STACK_OF(X509) *xchain; 2344 const char *name; 2345 unsigned char *cert_der[MAX_CERTS]; 2346 int cert_len[MAX_CERTS]; 2347 int i, cert_count, res; 2348 2349 res = 0; 2350 memset(cert_der, 0, sizeof(cert_der)); 2351 memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy); 2352 2353 /* Send the client certificate */ 2354 if (s->listener->ca_name[0]) { 2355 name = s->listener->ca_name; 2356 req_ca_vrfy.fallback = 0; 2357 } 2358 else { 2359 name = s->smtpname; 2360 req_ca_vrfy.fallback = 1; 2361 } 2362 2363 if (strlcpy(req_ca_vrfy.name, name, sizeof req_ca_vrfy.name) 2364 >= sizeof req_ca_vrfy.name) 2365 return 0; 2366 2367 x = SSL_get_peer_certificate(s->io.ssl); 2368 if (x == NULL) 2369 return 0; 2370 xchain = SSL_get_peer_cert_chain(s->io.ssl); 2371 2372 /* 2373 * Client provided a certificate and possibly a certificate chain. 2374 * SMTP can't verify because it does not have the information that 2375 * it needs, instead it will pass the certificate and chain to the 2376 * lookup process and wait for a reply. 2377 * 2378 */ 2379 2380 cert_len[0] = i2d_X509(x, &cert_der[0]); 2381 X509_free(x); 2382 2383 if (cert_len[0] < 0) { 2384 log_warnx("warn: failed to encode certificate"); 2385 goto end; 2386 } 2387 log_debug("debug: certificate 0: len=%d", cert_len[0]); 2388 if (cert_len[0] > (int)MAX_CERT_LEN) { 2389 log_warnx("warn: certificate too long"); 2390 goto end; 2391 } 2392 2393 if (xchain) { 2394 cert_count = sk_X509_num(xchain); 2395 log_debug("debug: certificate chain len: %d", cert_count); 2396 if (cert_count >= MAX_CERTS) { 2397 log_warnx("warn: certificate chain too long"); 2398 goto end; 2399 } 2400 } 2401 else 2402 cert_count = 0; 2403 2404 for (i = 0; i < cert_count; ++i) { 2405 x = sk_X509_value(xchain, i); 2406 cert_len[i+1] = i2d_X509(x, &cert_der[i+1]); 2407 if (cert_len[i+1] < 0) { 2408 log_warnx("warn: failed to encode certificate"); 2409 goto end; 2410 } 2411 log_debug("debug: certificate %i: len=%d", i+1, cert_len[i+1]); 2412 if (cert_len[i+1] > (int)MAX_CERT_LEN) { 2413 log_warnx("warn: certificate too long"); 2414 goto end; 2415 } 2416 } 2417 2418 tree_xset(&wait_ssl_verify, s->id, s); 2419 2420 /* Send the client certificate */ 2421 req_ca_vrfy.reqid = s->id; 2422 req_ca_vrfy.cert_len = cert_len[0]; 2423 req_ca_vrfy.n_chain = cert_count; 2424 iov[0].iov_base = &req_ca_vrfy; 2425 iov[0].iov_len = sizeof(req_ca_vrfy); 2426 iov[1].iov_base = cert_der[0]; 2427 iov[1].iov_len = cert_len[0]; 2428 m_composev(p_lka, IMSG_SMTP_TLS_VERIFY_CERT, 0, 0, -1, 2429 iov, nitems(iov)); 2430 2431 memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy); 2432 req_ca_vrfy.reqid = s->id; 2433 2434 /* Send the chain, one cert at a time */ 2435 for (i = 0; i < cert_count; ++i) { 2436 req_ca_vrfy.cert_len = cert_len[i+1]; 2437 iov[1].iov_base = cert_der[i+1]; 2438 iov[1].iov_len = cert_len[i+1]; 2439 m_composev(p_lka, IMSG_SMTP_TLS_VERIFY_CHAIN, 0, 0, -1, 2440 iov, nitems(iov)); 2441 } 2442 2443 /* Tell lookup process that it can start verifying, we're done */ 2444 memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy); 2445 req_ca_vrfy.reqid = s->id; 2446 m_compose(p_lka, IMSG_SMTP_TLS_VERIFY, 0, 0, -1, 2447 &req_ca_vrfy, sizeof req_ca_vrfy); 2448 2449 res = 1; 2450 2451 end: 2452 for (i = 0; i < MAX_CERTS; ++i) 2453 free(cert_der[i]); 2454 2455 return res; 2456 } 2457 2458 static void 2459 smtp_auth_failure_resume(int fd, short event, void *p) 2460 { 2461 struct smtp_session *s = p; 2462 2463 smtp_reply(s, "535 Authentication failed"); 2464 smtp_enter_state(s, STATE_HELO); 2465 io_reload(&s->io); 2466 } 2467 2468 static void 2469 smtp_auth_failure_pause(struct smtp_session *s) 2470 { 2471 struct timeval tv; 2472 2473 tv.tv_sec = 0; 2474 tv.tv_usec = arc4random_uniform(1000000); 2475 log_trace(TRACE_SMTP, "smtp: timing-attack protection triggered, " 2476 "will defer answer for %lu microseconds", tv.tv_usec); 2477 evtimer_set(&s->pause, smtp_auth_failure_resume, s); 2478 evtimer_add(&s->pause, &tv); 2479 } 2480 2481 static void 2482 smtp_queue_create_message(struct smtp_session *s) 2483 { 2484 m_create(p_queue, IMSG_SMTP_MESSAGE_CREATE, 0, 0, -1); 2485 m_add_id(p_queue, s->id); 2486 m_close(p_queue); 2487 tree_xset(&wait_queue_msg, s->id, s); 2488 } 2489 2490 static void 2491 smtp_queue_open_message(struct smtp_session *s) 2492 { 2493 m_create(p_queue, IMSG_SMTP_MESSAGE_OPEN, 0, 0, -1); 2494 m_add_id(p_queue, s->id); 2495 m_add_msgid(p_queue, s->tx->msgid); 2496 m_close(p_queue); 2497 tree_xset(&wait_queue_fd, s->id, s); 2498 } 2499 2500 static void 2501 smtp_queue_commit(struct smtp_session *s) 2502 { 2503 m_create(p_queue, IMSG_SMTP_MESSAGE_COMMIT, 0, 0, -1); 2504 m_add_id(p_queue, s->id); 2505 m_add_msgid(p_queue, s->tx->msgid); 2506 m_close(p_queue); 2507 tree_xset(&wait_queue_commit, s->id, s); 2508 } 2509 2510 static void 2511 smtp_queue_rollback(struct smtp_session *s) 2512 { 2513 m_create(p_queue, IMSG_SMTP_MESSAGE_ROLLBACK, 0, 0, -1); 2514 m_add_msgid(p_queue, s->tx->msgid); 2515 m_close(p_queue); 2516 } 2517 2518 static void 2519 smtp_filter_rset(struct smtp_session *s) 2520 { 2521 filter_event(s->id, EVENT_RESET); 2522 } 2523 2524 static void 2525 smtp_filter_tx_begin(struct smtp_session *s) 2526 { 2527 s->flags |= SF_FILTERTX; 2528 filter_event(s->id, EVENT_TX_BEGIN); 2529 } 2530 2531 static void 2532 smtp_filter_tx_commit(struct smtp_session *s) 2533 { 2534 s->flags &= ~SF_FILTERTX; 2535 filter_event(s->id, EVENT_TX_COMMIT); 2536 } 2537 2538 static void 2539 smtp_filter_tx_rollback(struct smtp_session *s) 2540 { 2541 s->flags &= ~SF_FILTERTX; 2542 filter_event(s->id, EVENT_TX_ROLLBACK); 2543 } 2544 2545 static void 2546 smtp_filter_disconnect(struct smtp_session *s) 2547 { 2548 filter_event(s->id, EVENT_DISCONNECT); 2549 } 2550 2551 static void 2552 smtp_filter_connect(struct smtp_session *s, struct sockaddr *sa) 2553 { 2554 char *filter; 2555 2556 tree_xset(&wait_filter, s->id, s); 2557 2558 filter = s->listener->filter[0] ? s->listener->filter : NULL; 2559 2560 filter_connect(s->id, sa, (struct sockaddr *)&s->ss, s->hostname, filter); 2561 } 2562 2563 static void 2564 smtp_filter_eom(struct smtp_session *s) 2565 { 2566 tree_xset(&wait_filter, s->id, s); 2567 filter_eom(s->id, QUERY_EOM, s->tx->odatalen); 2568 } 2569 2570 static void 2571 smtp_filter_helo(struct smtp_session *s) 2572 { 2573 tree_xset(&wait_filter, s->id, s); 2574 filter_line(s->id, QUERY_HELO, s->helo); 2575 } 2576 2577 static void 2578 smtp_filter_mail(struct smtp_session *s) 2579 { 2580 tree_xset(&wait_filter, s->id, s); 2581 filter_mailaddr(s->id, QUERY_MAIL, &s->tx->evp.sender); 2582 } 2583 2584 static void 2585 smtp_filter_rcpt(struct smtp_session *s) 2586 { 2587 tree_xset(&wait_filter, s->id, s); 2588 filter_mailaddr(s->id, QUERY_RCPT, &s->tx->evp.rcpt); 2589 } 2590 2591 static void 2592 smtp_filter_data(struct smtp_session *s) 2593 { 2594 tree_xset(&wait_filter, s->id, s); 2595 filter_line(s->id, QUERY_DATA, NULL); 2596 } 2597 2598 static void 2599 smtp_filter_dataline(struct smtp_session *s, const char *line) 2600 { 2601 int ret; 2602 2603 log_trace(TRACE_SMTP, "<<< [MSG] %s", line); 2604 2605 /* ignore data line if an error flag is set */ 2606 if (s->tx->msgflags & MF_ERROR) 2607 return; 2608 2609 /* escape lines starting with a '.' */ 2610 if (line[0] == '.') 2611 line += 1; 2612 2613 /* account for newline */ 2614 s->tx->datain += strlen(line) + 1; 2615 if (s->tx->datain > env->sc_maxsize) { 2616 s->tx->msgflags |= MF_ERROR_SIZE; 2617 return; 2618 } 2619 2620 if (!s->tx->hdrdone) { 2621 2622 /* folded header that must be skipped */ 2623 if (isspace((unsigned char)line[0]) && s->tx->skiphdr) 2624 return; 2625 s->tx->skiphdr = 0; 2626 2627 /* BCC should be stripped from headers */ 2628 if (strncasecmp("bcc:", line, 4) == 0) { 2629 s->tx->skiphdr = 1; 2630 return; 2631 } 2632 2633 /* check for loop */ 2634 if (strncasecmp("Received: ", line, 10) == 0) 2635 s->tx->rcvcount++; 2636 if (s->tx->rcvcount == MAX_HOPS_COUNT) { 2637 s->tx->msgflags |= MF_ERROR_LOOP; 2638 log_warnx("warn: loop detected"); 2639 return; 2640 } 2641 2642 if (line[0] == '\0') 2643 s->tx->hdrdone = 1; 2644 } 2645 2646 ret = rfc2822_parser_feed(&s->tx->rfc2822_parser, line); 2647 if (ret == -1) { 2648 s->tx->msgflags |= MF_ERROR_RESOURCES; 2649 return; 2650 } 2651 2652 if (ret == 0) { 2653 s->tx->msgflags |= MF_ERROR_MALFORMED; 2654 return; 2655 } 2656 2657 if (iobuf_queued(&s->tx->obuf) > DATA_HIWAT && !(s->io.flags & IO_PAUSE_IN)) { 2658 log_debug("debug: smtp: %p: filter congestion over: pausing session", s); 2659 io_pause(&s->io, IO_PAUSE_IN); 2660 } 2661 io_reload(&s->tx->oev); 2662 } 2663 2664 #define CASE(x) case x : return #x 2665 2666 const char * 2667 smtp_strstate(int state) 2668 { 2669 static char buf[32]; 2670 2671 switch (state) { 2672 CASE(STATE_NEW); 2673 CASE(STATE_CONNECTED); 2674 CASE(STATE_TLS); 2675 CASE(STATE_HELO); 2676 CASE(STATE_AUTH_INIT); 2677 CASE(STATE_AUTH_USERNAME); 2678 CASE(STATE_AUTH_PASSWORD); 2679 CASE(STATE_AUTH_FINALIZE); 2680 CASE(STATE_BODY); 2681 CASE(STATE_QUIT); 2682 default: 2683 (void)snprintf(buf, sizeof(buf), "STATE_??? (%d)", state); 2684 return (buf); 2685 } 2686 } 2687