1 /* $OpenBSD: smtp_session.c,v 1.424 2020/02/03 15:53:52 gilles 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 #include "rfc5322.h" 48 49 #define SMTP_LINE_MAX 65535 50 #define DATA_HIWAT 65535 51 #define APPEND_DOMAIN_BUFFER_SIZE SMTP_LINE_MAX 52 53 enum smtp_state { 54 STATE_NEW = 0, 55 STATE_CONNECTED, 56 STATE_TLS, 57 STATE_HELO, 58 STATE_AUTH_INIT, 59 STATE_AUTH_USERNAME, 60 STATE_AUTH_PASSWORD, 61 STATE_AUTH_FINALIZE, 62 STATE_BODY, 63 STATE_QUIT, 64 }; 65 66 enum session_flags { 67 SF_EHLO = 0x0001, 68 SF_8BITMIME = 0x0002, 69 SF_SECURE = 0x0004, 70 SF_AUTHENTICATED = 0x0008, 71 SF_BOUNCE = 0x0010, 72 SF_VERIFIED = 0x0020, 73 SF_BADINPUT = 0x0080, 74 }; 75 76 enum { 77 TX_OK = 0, 78 TX_ERROR_ENVELOPE, 79 TX_ERROR_SIZE, 80 TX_ERROR_IO, 81 TX_ERROR_LOOP, 82 TX_ERROR_MALFORMED, 83 TX_ERROR_RESOURCES, 84 TX_ERROR_INTERNAL, 85 }; 86 87 enum smtp_command { 88 CMD_HELO = 0, 89 CMD_EHLO, 90 CMD_STARTTLS, 91 CMD_AUTH, 92 CMD_MAIL_FROM, 93 CMD_RCPT_TO, 94 CMD_DATA, 95 CMD_RSET, 96 CMD_QUIT, 97 CMD_HELP, 98 CMD_WIZ, 99 CMD_NOOP, 100 CMD_COMMIT, 101 }; 102 103 struct smtp_rcpt { 104 TAILQ_ENTRY(smtp_rcpt) entry; 105 uint64_t evpid; 106 struct mailaddr maddr; 107 size_t destcount; 108 }; 109 110 struct smtp_tx { 111 struct smtp_session *session; 112 uint32_t msgid; 113 114 struct envelope evp; 115 size_t rcptcount; 116 size_t destcount; 117 TAILQ_HEAD(, smtp_rcpt) rcpts; 118 119 time_t time; 120 int error; 121 size_t datain; 122 size_t odatalen; 123 FILE *ofile; 124 struct io *filter; 125 struct rfc5322_parser *parser; 126 int rcvcount; 127 int has_date; 128 int has_message_id; 129 130 uint8_t junk; 131 }; 132 133 struct smtp_session { 134 uint64_t id; 135 struct io *io; 136 struct listener *listener; 137 void *ssl_ctx; 138 struct sockaddr_storage ss; 139 char rdns[HOST_NAME_MAX+1]; 140 char smtpname[HOST_NAME_MAX+1]; 141 int fcrdns; 142 143 int flags; 144 enum smtp_state state; 145 146 uint8_t banner_sent; 147 char helo[LINE_MAX]; 148 char cmd[LINE_MAX]; 149 char username[SMTPD_MAXMAILADDRSIZE]; 150 151 size_t mailcount; 152 struct event pause; 153 154 struct smtp_tx *tx; 155 156 enum smtp_command last_cmd; 157 enum filter_phase filter_phase; 158 const char *filter_param; 159 160 uint8_t junk; 161 }; 162 163 #define ADVERTISE_TLS(s) \ 164 ((s)->listener->flags & F_STARTTLS && !((s)->flags & SF_SECURE)) 165 166 #define ADVERTISE_AUTH(s) \ 167 ((s)->listener->flags & F_AUTH && (s)->flags & SF_SECURE && \ 168 !((s)->flags & SF_AUTHENTICATED)) 169 170 #define ADVERTISE_EXT_DSN(s) \ 171 ((s)->listener->flags & F_EXT_DSN) 172 173 #define SESSION_FILTERED(s) \ 174 ((s)->listener->flags & F_FILTERED) 175 176 #define SESSION_DATA_FILTERED(s) \ 177 ((s)->listener->flags & F_FILTERED) 178 179 180 static int smtp_mailaddr(struct mailaddr *, char *, int, char **, const char *); 181 static void smtp_session_init(void); 182 static void smtp_lookup_servername(struct smtp_session *); 183 static void smtp_getnameinfo_cb(void *, int, const char *, const char *); 184 static void smtp_getaddrinfo_cb(void *, int, struct addrinfo *); 185 static void smtp_connected(struct smtp_session *); 186 static void smtp_send_banner(struct smtp_session *); 187 static void smtp_tls_verified(struct smtp_session *); 188 static void smtp_io(struct io *, int, void *); 189 static void smtp_enter_state(struct smtp_session *, int); 190 static void smtp_reply(struct smtp_session *, char *, ...); 191 static void smtp_command(struct smtp_session *, char *); 192 static void smtp_rfc4954_auth_plain(struct smtp_session *, char *); 193 static void smtp_rfc4954_auth_login(struct smtp_session *, char *); 194 static void smtp_free(struct smtp_session *, const char *); 195 static const char *smtp_strstate(int); 196 static void smtp_cert_init(struct smtp_session *); 197 static void smtp_cert_init_cb(void *, int, const char *, const void *, size_t); 198 static void smtp_cert_verify(struct smtp_session *); 199 static void smtp_cert_verify_cb(void *, int); 200 static void smtp_auth_failure_pause(struct smtp_session *); 201 static void smtp_auth_failure_resume(int, short, void *); 202 203 static int smtp_tx(struct smtp_session *); 204 static void smtp_tx_free(struct smtp_tx *); 205 static void smtp_tx_create_message(struct smtp_tx *); 206 static void smtp_tx_mail_from(struct smtp_tx *, const char *); 207 static void smtp_tx_rcpt_to(struct smtp_tx *, const char *); 208 static void smtp_tx_open_message(struct smtp_tx *); 209 static void smtp_tx_commit(struct smtp_tx *); 210 static void smtp_tx_rollback(struct smtp_tx *); 211 static int smtp_tx_dataline(struct smtp_tx *, const char *); 212 static int smtp_tx_filtered_dataline(struct smtp_tx *, const char *); 213 static void smtp_tx_eom(struct smtp_tx *); 214 static void smtp_filter_fd(struct smtp_tx *, int); 215 static int smtp_message_fd(struct smtp_tx *, int); 216 static void smtp_message_begin(struct smtp_tx *); 217 static void smtp_message_end(struct smtp_tx *); 218 static int smtp_filter_printf(struct smtp_tx *, const char *, ...) 219 __attribute__((__format__ (printf, 2, 3))); 220 static int smtp_message_printf(struct smtp_tx *, const char *, ...) 221 __attribute__((__format__ (printf, 2, 3))); 222 223 static int smtp_check_rset(struct smtp_session *, const char *); 224 static int smtp_check_helo(struct smtp_session *, const char *); 225 static int smtp_check_ehlo(struct smtp_session *, const char *); 226 static int smtp_check_auth(struct smtp_session *s, const char *); 227 static int smtp_check_starttls(struct smtp_session *, const char *); 228 static int smtp_check_mail_from(struct smtp_session *, const char *); 229 static int smtp_check_rcpt_to(struct smtp_session *, const char *); 230 static int smtp_check_data(struct smtp_session *, const char *); 231 static int smtp_check_noparam(struct smtp_session *, const char *); 232 233 static void smtp_filter_phase(enum filter_phase, struct smtp_session *, const char *); 234 235 static void smtp_proceed_connected(struct smtp_session *); 236 static void smtp_proceed_rset(struct smtp_session *, const char *); 237 static void smtp_proceed_helo(struct smtp_session *, const char *); 238 static void smtp_proceed_ehlo(struct smtp_session *, const char *); 239 static void smtp_proceed_auth(struct smtp_session *, const char *); 240 static void smtp_proceed_starttls(struct smtp_session *, const char *); 241 static void smtp_proceed_mail_from(struct smtp_session *, const char *); 242 static void smtp_proceed_rcpt_to(struct smtp_session *, const char *); 243 static void smtp_proceed_data(struct smtp_session *, const char *); 244 static void smtp_proceed_noop(struct smtp_session *, const char *); 245 static void smtp_proceed_help(struct smtp_session *, const char *); 246 static void smtp_proceed_wiz(struct smtp_session *, const char *); 247 static void smtp_proceed_quit(struct smtp_session *, const char *); 248 static void smtp_proceed_commit(struct smtp_session *, const char *); 249 static void smtp_proceed_rollback(struct smtp_session *, const char *); 250 251 static void smtp_filter_begin(struct smtp_session *); 252 static void smtp_filter_end(struct smtp_session *); 253 static void smtp_filter_data_begin(struct smtp_session *); 254 static void smtp_filter_data_end(struct smtp_session *); 255 256 static void smtp_report_link_connect(struct smtp_session *, const char *, int, 257 const struct sockaddr_storage *, 258 const struct sockaddr_storage *); 259 static void smtp_report_link_greeting(struct smtp_session *, const char *); 260 static void smtp_report_link_identify(struct smtp_session *, const char *, const char *); 261 static void smtp_report_link_tls(struct smtp_session *, const char *); 262 static void smtp_report_link_disconnect(struct smtp_session *); 263 static void smtp_report_link_auth(struct smtp_session *, const char *, const char *); 264 static void smtp_report_tx_reset(struct smtp_session *, uint32_t); 265 static void smtp_report_tx_begin(struct smtp_session *, uint32_t); 266 static void smtp_report_tx_mail(struct smtp_session *, uint32_t, const char *, int); 267 static void smtp_report_tx_rcpt(struct smtp_session *, uint32_t, const char *, int); 268 static void smtp_report_tx_envelope(struct smtp_session *, uint32_t, uint64_t); 269 static void smtp_report_tx_data(struct smtp_session *, uint32_t, int); 270 static void smtp_report_tx_commit(struct smtp_session *, uint32_t, size_t); 271 static void smtp_report_tx_rollback(struct smtp_session *, uint32_t); 272 static void smtp_report_protocol_client(struct smtp_session *, const char *); 273 static void smtp_report_protocol_server(struct smtp_session *, const char *); 274 static void smtp_report_filter_response(struct smtp_session *, int, int, const char *); 275 static void smtp_report_timeout(struct smtp_session *); 276 277 278 static struct { 279 int code; 280 enum filter_phase filter_phase; 281 const char *cmd; 282 283 int (*check)(struct smtp_session *, const char *); 284 void (*proceed)(struct smtp_session *, const char *); 285 } commands[] = { 286 { CMD_HELO, FILTER_HELO, "HELO", smtp_check_helo, smtp_proceed_helo }, 287 { CMD_EHLO, FILTER_EHLO, "EHLO", smtp_check_ehlo, smtp_proceed_ehlo }, 288 { CMD_STARTTLS, FILTER_STARTTLS, "STARTTLS", smtp_check_starttls, smtp_proceed_starttls }, 289 { CMD_AUTH, FILTER_AUTH, "AUTH", smtp_check_auth, smtp_proceed_auth }, 290 { CMD_MAIL_FROM, FILTER_MAIL_FROM, "MAIL FROM", smtp_check_mail_from, smtp_proceed_mail_from }, 291 { CMD_RCPT_TO, FILTER_RCPT_TO, "RCPT TO", smtp_check_rcpt_to, smtp_proceed_rcpt_to }, 292 { CMD_DATA, FILTER_DATA, "DATA", smtp_check_data, smtp_proceed_data }, 293 { CMD_RSET, FILTER_RSET, "RSET", smtp_check_rset, smtp_proceed_rset }, 294 { CMD_QUIT, FILTER_QUIT, "QUIT", smtp_check_noparam, smtp_proceed_quit }, 295 { CMD_NOOP, FILTER_NOOP, "NOOP", smtp_check_noparam, smtp_proceed_noop }, 296 { CMD_HELP, FILTER_HELP, "HELP", smtp_check_noparam, smtp_proceed_help }, 297 { CMD_WIZ, FILTER_WIZ, "WIZ", smtp_check_noparam, smtp_proceed_wiz }, 298 { CMD_COMMIT, FILTER_COMMIT, ".", smtp_check_noparam, smtp_proceed_commit }, 299 { -1, 0, NULL, NULL }, 300 }; 301 302 static struct tree wait_lka_helo; 303 static struct tree wait_lka_mail; 304 static struct tree wait_lka_rcpt; 305 static struct tree wait_parent_auth; 306 static struct tree wait_queue_msg; 307 static struct tree wait_queue_fd; 308 static struct tree wait_queue_commit; 309 static struct tree wait_ssl_init; 310 static struct tree wait_ssl_verify; 311 static struct tree wait_filters; 312 static struct tree wait_filter_fd; 313 314 static void 315 header_append_domain_buffer(char *buffer, char *domain, size_t len) 316 { 317 size_t i; 318 int escape, quote, comment, bracket; 319 int has_domain, has_bracket, has_group; 320 int pos_bracket, pos_component, pos_insert; 321 char copy[APPEND_DOMAIN_BUFFER_SIZE]; 322 323 escape = quote = comment = bracket = 0; 324 has_domain = has_bracket = has_group = 0; 325 pos_bracket = pos_insert = pos_component = 0; 326 for (i = 0; buffer[i]; ++i) { 327 if (buffer[i] == '(' && !escape && !quote) 328 comment++; 329 if (buffer[i] == '"' && !escape && !comment) 330 quote = !quote; 331 if (buffer[i] == ')' && !escape && !quote && comment) 332 comment--; 333 if (buffer[i] == '\\' && !escape && !comment && !quote) 334 escape = 1; 335 else 336 escape = 0; 337 if (buffer[i] == '<' && !escape && !comment && !quote && !bracket) { 338 bracket++; 339 has_bracket = 1; 340 } 341 if (buffer[i] == '>' && !escape && !comment && !quote && bracket) { 342 bracket--; 343 pos_bracket = i; 344 } 345 if (buffer[i] == '@' && !escape && !comment && !quote) 346 has_domain = 1; 347 if (buffer[i] == ':' && !escape && !comment && !quote) 348 has_group = 1; 349 350 /* update insert point if not in comment and not on a whitespace */ 351 if (!comment && buffer[i] != ')' && !isspace((unsigned char)buffer[i])) 352 pos_component = i; 353 } 354 355 /* parse error, do not attempt to modify */ 356 if (escape || quote || comment || bracket) 357 return; 358 359 /* domain already present, no need to modify */ 360 if (has_domain) 361 return; 362 363 /* address is group, skip */ 364 if (has_group) 365 return; 366 367 /* there's an address between brackets, just append domain */ 368 if (has_bracket) { 369 pos_bracket--; 370 while (isspace((unsigned char)buffer[pos_bracket])) 371 pos_bracket--; 372 if (buffer[pos_bracket] == '<') 373 return; 374 pos_insert = pos_bracket + 1; 375 } 376 else { 377 /* otherwise append address to last component */ 378 pos_insert = pos_component + 1; 379 380 /* empty address */ 381 if (buffer[pos_component] == '\0' || 382 isspace((unsigned char)buffer[pos_component])) 383 return; 384 } 385 386 if (snprintf(copy, sizeof copy, "%.*s@%s%s", 387 (int)pos_insert, buffer, 388 domain, 389 buffer+pos_insert) >= (int)sizeof copy) 390 return; 391 392 memcpy(buffer, copy, len); 393 } 394 395 static void 396 header_address_rewrite_buffer(char *buffer, const char *address, size_t len) 397 { 398 size_t i; 399 int address_len; 400 int escape, quote, comment, bracket; 401 int has_bracket, has_group; 402 int pos_bracket_beg, pos_bracket_end, pos_component_beg, pos_component_end; 403 int insert_beg, insert_end; 404 char copy[APPEND_DOMAIN_BUFFER_SIZE]; 405 406 escape = quote = comment = bracket = 0; 407 has_bracket = has_group = 0; 408 pos_bracket_beg = pos_bracket_end = pos_component_beg = pos_component_end = 0; 409 for (i = 0; buffer[i]; ++i) { 410 if (buffer[i] == '(' && !escape && !quote) 411 comment++; 412 if (buffer[i] == '"' && !escape && !comment) 413 quote = !quote; 414 if (buffer[i] == ')' && !escape && !quote && comment) 415 comment--; 416 if (buffer[i] == '\\' && !escape && !comment && !quote) 417 escape = 1; 418 else 419 escape = 0; 420 if (buffer[i] == '<' && !escape && !comment && !quote && !bracket) { 421 bracket++; 422 has_bracket = 1; 423 pos_bracket_beg = i+1; 424 } 425 if (buffer[i] == '>' && !escape && !comment && !quote && bracket) { 426 bracket--; 427 pos_bracket_end = i; 428 } 429 if (buffer[i] == ':' && !escape && !comment && !quote) 430 has_group = 1; 431 432 /* update insert point if not in comment and not on a whitespace */ 433 if (!comment && buffer[i] != ')' && !isspace((unsigned char)buffer[i])) 434 pos_component_end = i; 435 } 436 437 /* parse error, do not attempt to modify */ 438 if (escape || quote || comment || bracket) 439 return; 440 441 /* address is group, skip */ 442 if (has_group) 443 return; 444 445 /* there's an address between brackets, just replace everything brackets */ 446 if (has_bracket) { 447 insert_beg = pos_bracket_beg; 448 insert_end = pos_bracket_end; 449 } 450 else { 451 if (pos_component_end == 0) 452 pos_component_beg = 0; 453 else { 454 for (pos_component_beg = pos_component_end; pos_component_beg >= 0; --pos_component_beg) 455 if (buffer[pos_component_beg] == ')' || isspace(buffer[pos_component_beg])) 456 break; 457 pos_component_beg += 1; 458 pos_component_end += 1; 459 } 460 insert_beg = pos_component_beg; 461 insert_end = pos_component_end; 462 } 463 464 /* check that masquerade won' t overflow */ 465 address_len = strlen(address); 466 if (strlen(buffer) - (insert_end - insert_beg) + address_len >= len) 467 return; 468 469 (void)strlcpy(copy, buffer, sizeof copy); 470 (void)strlcpy(copy+insert_beg, address, sizeof (copy) - insert_beg); 471 (void)strlcat(copy, buffer+insert_end, sizeof (copy)); 472 memcpy(buffer, copy, len); 473 } 474 475 static void 476 header_domain_append_callback(struct smtp_tx *tx, const char *hdr, 477 const char *val) 478 { 479 size_t i, j, linelen; 480 int escape, quote, comment, skip; 481 char buffer[APPEND_DOMAIN_BUFFER_SIZE]; 482 const char *line, *end; 483 484 if (smtp_message_printf(tx, "%s:", hdr) == -1) 485 return; 486 487 j = 0; 488 escape = quote = comment = skip = 0; 489 memset(buffer, 0, sizeof buffer); 490 491 for (line = val; line; line = end) { 492 end = strchr(line, '\n'); 493 if (end) { 494 linelen = end - line; 495 end++; 496 } 497 else 498 linelen = strlen(line); 499 500 for (i = 0; i < linelen; ++i) { 501 if (line[i] == '(' && !escape && !quote) 502 comment++; 503 if (line[i] == '"' && !escape && !comment) 504 quote = !quote; 505 if (line[i] == ')' && !escape && !quote && comment) 506 comment--; 507 if (line[i] == '\\' && !escape && !comment && !quote) 508 escape = 1; 509 else 510 escape = 0; 511 512 /* found a separator, buffer contains a full address */ 513 if (line[i] == ',' && !escape && !quote && !comment) { 514 if (!skip && j + strlen(tx->session->listener->hostname) + 1 < sizeof buffer) { 515 header_append_domain_buffer(buffer, tx->session->listener->hostname, sizeof buffer); 516 if (tx->session->flags & SF_AUTHENTICATED && 517 tx->session->listener->sendertable[0] && 518 tx->session->listener->flags & F_MASQUERADE && 519 !(strcasecmp(hdr, "From"))) 520 header_address_rewrite_buffer(buffer, mailaddr_to_text(&tx->evp.sender), 521 sizeof buffer); 522 } 523 if (smtp_message_printf(tx, "%s,", buffer) == -1) 524 return; 525 j = 0; 526 skip = 0; 527 memset(buffer, 0, sizeof buffer); 528 } 529 else { 530 if (skip) { 531 if (smtp_message_printf(tx, "%c", line[i]) == -1) 532 return; 533 } 534 else { 535 buffer[j++] = line[i]; 536 if (j == sizeof (buffer) - 1) { 537 if (smtp_message_printf(tx, "%s", buffer) == -1) 538 return; 539 skip = 1; 540 j = 0; 541 memset(buffer, 0, sizeof buffer); 542 } 543 } 544 } 545 } 546 if (skip) { 547 if (smtp_message_printf(tx, "\n") == -1) 548 return; 549 } 550 else { 551 buffer[j++] = '\n'; 552 if (j == sizeof (buffer) - 1) { 553 if (smtp_message_printf(tx, "%s", buffer) == -1) 554 return; 555 skip = 1; 556 j = 0; 557 memset(buffer, 0, sizeof buffer); 558 } 559 } 560 } 561 562 /* end of header, if buffer is not empty we'll process it */ 563 if (buffer[0]) { 564 if (j + strlen(tx->session->listener->hostname) + 1 < sizeof buffer) { 565 header_append_domain_buffer(buffer, tx->session->listener->hostname, sizeof buffer); 566 if (tx->session->flags & SF_AUTHENTICATED && 567 tx->session->listener->sendertable[0] && 568 tx->session->listener->flags & F_MASQUERADE && 569 !(strcasecmp(hdr, "From"))) 570 header_address_rewrite_buffer(buffer, mailaddr_to_text(&tx->evp.sender), 571 sizeof buffer); 572 } 573 smtp_message_printf(tx, "%s", buffer); 574 } 575 } 576 577 static void 578 smtp_session_init(void) 579 { 580 static int init = 0; 581 582 if (!init) { 583 tree_init(&wait_lka_helo); 584 tree_init(&wait_lka_mail); 585 tree_init(&wait_lka_rcpt); 586 tree_init(&wait_parent_auth); 587 tree_init(&wait_queue_msg); 588 tree_init(&wait_queue_fd); 589 tree_init(&wait_queue_commit); 590 tree_init(&wait_ssl_init); 591 tree_init(&wait_ssl_verify); 592 tree_init(&wait_filters); 593 tree_init(&wait_filter_fd); 594 init = 1; 595 } 596 } 597 598 int 599 smtp_session(struct listener *listener, int sock, 600 const struct sockaddr_storage *ss, const char *hostname, struct io *io) 601 { 602 struct smtp_session *s; 603 604 smtp_session_init(); 605 606 if ((s = calloc(1, sizeof(*s))) == NULL) 607 return (-1); 608 609 s->id = generate_uid(); 610 s->listener = listener; 611 memmove(&s->ss, ss, sizeof(*ss)); 612 613 if (io != NULL) 614 s->io = io; 615 else 616 s->io = io_new(); 617 618 io_set_callback(s->io, smtp_io, s); 619 io_set_fd(s->io, sock); 620 io_set_timeout(s->io, SMTPD_SESSION_TIMEOUT * 1000); 621 io_set_write(s->io); 622 s->state = STATE_NEW; 623 624 (void)strlcpy(s->smtpname, listener->hostname, sizeof(s->smtpname)); 625 626 log_trace(TRACE_SMTP, "smtp: %p: connected to listener %p " 627 "[hostname=%s, port=%d, tag=%s]", s, listener, 628 listener->hostname, ntohs(listener->port), listener->tag); 629 630 /* For local enqueueing, the hostname is already set */ 631 if (hostname) { 632 s->flags |= SF_AUTHENTICATED; 633 /* A bit of a hack */ 634 if (!strcmp(hostname, "localhost")) 635 s->flags |= SF_BOUNCE; 636 (void)strlcpy(s->rdns, hostname, sizeof(s->rdns)); 637 s->fcrdns = 1; 638 smtp_lookup_servername(s); 639 } else { 640 resolver_getnameinfo((struct sockaddr *)&s->ss, NI_NAMEREQD, 641 smtp_getnameinfo_cb, s); 642 } 643 644 /* session may have been freed by now */ 645 646 return (0); 647 } 648 649 static void 650 smtp_getnameinfo_cb(void *arg, int gaierrno, const char *host, const char *serv) 651 { 652 struct smtp_session *s = arg; 653 struct addrinfo hints; 654 655 if (gaierrno) { 656 (void)strlcpy(s->rdns, "<unknown>", sizeof(s->rdns)); 657 658 if (gaierrno == EAI_NODATA || gaierrno == EAI_NONAME) 659 s->fcrdns = 0; 660 else { 661 log_warnx("getnameinfo: %s: %s", ss_to_text(&s->ss), 662 gai_strerror(gaierrno)); 663 s->fcrdns = -1; 664 } 665 666 smtp_lookup_servername(s); 667 return; 668 } 669 670 (void)strlcpy(s->rdns, host, sizeof(s->rdns)); 671 672 memset(&hints, 0, sizeof(hints)); 673 hints.ai_family = s->ss.ss_family; 674 hints.ai_socktype = SOCK_STREAM; 675 resolver_getaddrinfo(s->rdns, NULL, &hints, smtp_getaddrinfo_cb, s); 676 } 677 678 static void 679 smtp_getaddrinfo_cb(void *arg, int gaierrno, struct addrinfo *ai0) 680 { 681 struct smtp_session *s = arg; 682 struct addrinfo *ai; 683 char fwd[64], rev[64]; 684 685 if (gaierrno) { 686 if (gaierrno == EAI_NODATA || gaierrno == EAI_NONAME) 687 s->fcrdns = 0; 688 else { 689 log_warnx("getaddrinfo: %s: %s", s->rdns, 690 gai_strerror(gaierrno)); 691 s->fcrdns = -1; 692 } 693 } 694 else { 695 strlcpy(rev, ss_to_text(&s->ss), sizeof(rev)); 696 for (ai = ai0; ai; ai = ai->ai_next) { 697 strlcpy(fwd, sa_to_text(ai->ai_addr), sizeof(fwd)); 698 if (!strcmp(fwd, rev)) { 699 s->fcrdns = 1; 700 break; 701 } 702 } 703 freeaddrinfo(ai0); 704 } 705 706 smtp_lookup_servername(s); 707 } 708 709 void 710 smtp_session_imsg(struct mproc *p, struct imsg *imsg) 711 { 712 struct smtp_session *s; 713 struct smtp_rcpt *rcpt; 714 char user[SMTPD_MAXMAILADDRSIZE]; 715 char tmp[SMTP_LINE_MAX]; 716 struct msg m; 717 const char *line, *helo; 718 uint64_t reqid, evpid; 719 uint32_t msgid; 720 int status, success; 721 int filter_response; 722 const char *filter_param; 723 uint8_t i; 724 725 switch (imsg->hdr.type) { 726 727 case IMSG_SMTP_CHECK_SENDER: 728 m_msg(&m, imsg); 729 m_get_id(&m, &reqid); 730 m_get_int(&m, &status); 731 m_end(&m); 732 s = tree_xpop(&wait_lka_mail, reqid); 733 switch (status) { 734 case LKA_OK: 735 smtp_tx_create_message(s->tx); 736 break; 737 738 case LKA_PERMFAIL: 739 smtp_tx_free(s->tx); 740 smtp_reply(s, "%d %s", 530, "Sender rejected"); 741 break; 742 case LKA_TEMPFAIL: 743 smtp_tx_free(s->tx); 744 smtp_reply(s, "421 %s Temporary Error", 745 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 746 break; 747 } 748 return; 749 750 case IMSG_SMTP_EXPAND_RCPT: 751 m_msg(&m, imsg); 752 m_get_id(&m, &reqid); 753 m_get_int(&m, &status); 754 m_get_string(&m, &line); 755 m_end(&m); 756 s = tree_xpop(&wait_lka_rcpt, reqid); 757 758 tmp[0] = '\0'; 759 if (s->tx->evp.rcpt.user[0]) { 760 (void)strlcpy(tmp, s->tx->evp.rcpt.user, sizeof tmp); 761 if (s->tx->evp.rcpt.domain[0]) { 762 (void)strlcat(tmp, "@", sizeof tmp); 763 (void)strlcat(tmp, s->tx->evp.rcpt.domain, 764 sizeof tmp); 765 } 766 } 767 768 switch (status) { 769 case LKA_OK: 770 fatalx("unexpected ok"); 771 case LKA_PERMFAIL: 772 smtp_reply(s, "%s: <%s>", line, tmp); 773 break; 774 case LKA_TEMPFAIL: 775 smtp_reply(s, "%s: <%s>", line, tmp); 776 break; 777 } 778 return; 779 780 case IMSG_SMTP_LOOKUP_HELO: 781 m_msg(&m, imsg); 782 m_get_id(&m, &reqid); 783 s = tree_xpop(&wait_lka_helo, reqid); 784 m_get_int(&m, &status); 785 if (status == LKA_OK) { 786 m_get_string(&m, &helo); 787 (void)strlcpy(s->smtpname, helo, sizeof(s->smtpname)); 788 } 789 m_end(&m); 790 smtp_connected(s); 791 return; 792 793 case IMSG_SMTP_MESSAGE_CREATE: 794 m_msg(&m, imsg); 795 m_get_id(&m, &reqid); 796 m_get_int(&m, &success); 797 s = tree_xpop(&wait_queue_msg, reqid); 798 if (success) { 799 m_get_msgid(&m, &msgid); 800 s->tx->msgid = msgid; 801 s->tx->evp.id = msgid_to_evpid(msgid); 802 s->tx->rcptcount = 0; 803 smtp_reply(s, "250 %s Ok", 804 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 805 } else { 806 smtp_reply(s, "421 %s Temporary Error", 807 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 808 smtp_tx_free(s->tx); 809 smtp_enter_state(s, STATE_QUIT); 810 } 811 m_end(&m); 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 return; 828 } 829 830 log_debug("smtp: %p: fd %d from queue", s, imsg->fd); 831 832 if (smtp_message_fd(s->tx, imsg->fd)) { 833 if (!SESSION_DATA_FILTERED(s)) 834 smtp_message_begin(s->tx); 835 else 836 smtp_filter_data_begin(s); 837 } 838 return; 839 840 case IMSG_FILTER_SMTP_DATA_BEGIN: 841 m_msg(&m, imsg); 842 m_get_id(&m, &reqid); 843 m_get_int(&m, &success); 844 m_end(&m); 845 846 s = tree_xpop(&wait_filter_fd, reqid); 847 if (!success || imsg->fd == -1) { 848 if (imsg->fd != -1) 849 close(imsg->fd); 850 smtp_reply(s, "421 %s Temporary Error", 851 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 852 smtp_enter_state(s, STATE_QUIT); 853 return; 854 } 855 856 log_debug("smtp: %p: fd %d from lka", s, imsg->fd); 857 858 smtp_filter_fd(s->tx, imsg->fd); 859 smtp_message_begin(s->tx); 860 return; 861 862 case IMSG_QUEUE_ENVELOPE_SUBMIT: 863 m_msg(&m, imsg); 864 m_get_id(&m, &reqid); 865 m_get_int(&m, &success); 866 s = tree_xget(&wait_lka_rcpt, reqid); 867 if (success) { 868 m_get_evpid(&m, &evpid); 869 s->tx->evp.id = evpid; 870 s->tx->destcount++; 871 smtp_report_tx_envelope(s, s->tx->msgid, evpid); 872 } 873 else 874 s->tx->error = TX_ERROR_ENVELOPE; 875 m_end(&m); 876 return; 877 878 case IMSG_QUEUE_ENVELOPE_COMMIT: 879 m_msg(&m, imsg); 880 m_get_id(&m, &reqid); 881 m_get_int(&m, &success); 882 m_end(&m); 883 if (!success) 884 fatalx("commit evp failed: not supposed to happen"); 885 s = tree_xpop(&wait_lka_rcpt, reqid); 886 if (s->tx->error) { 887 /* 888 * If an envelope failed, we can't cancel the last 889 * RCPT only so we must cancel the whole transaction 890 * and close the connection. 891 */ 892 smtp_reply(s, "421 %s Temporary failure", 893 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 894 smtp_enter_state(s, STATE_QUIT); 895 } 896 else { 897 rcpt = xcalloc(1, sizeof(*rcpt)); 898 rcpt->evpid = s->tx->evp.id; 899 rcpt->destcount = s->tx->destcount; 900 rcpt->maddr = s->tx->evp.rcpt; 901 TAILQ_INSERT_TAIL(&s->tx->rcpts, rcpt, entry); 902 903 s->tx->destcount = 0; 904 s->tx->rcptcount++; 905 smtp_reply(s, "250 %s %s: Recipient ok", 906 esc_code(ESC_STATUS_OK, ESC_DESTINATION_ADDRESS_VALID), 907 esc_description(ESC_DESTINATION_ADDRESS_VALID)); 908 } 909 return; 910 911 case IMSG_SMTP_MESSAGE_COMMIT: 912 m_msg(&m, imsg); 913 m_get_id(&m, &reqid); 914 m_get_int(&m, &success); 915 m_end(&m); 916 s = tree_xpop(&wait_queue_commit, reqid); 917 if (!success) { 918 smtp_reply(s, "421 %s Temporary failure", 919 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 920 smtp_tx_free(s->tx); 921 smtp_enter_state(s, STATE_QUIT); 922 return; 923 } 924 925 smtp_reply(s, "250 %s %08x Message accepted for delivery", 926 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS), 927 s->tx->msgid); 928 smtp_report_tx_commit(s, s->tx->msgid, s->tx->odatalen); 929 smtp_report_tx_reset(s, s->tx->msgid); 930 931 log_info("%016"PRIx64" smtp message " 932 "msgid=%08x size=%zu nrcpt=%zu proto=%s", 933 s->id, 934 s->tx->msgid, 935 s->tx->odatalen, 936 s->tx->rcptcount, 937 s->flags & SF_EHLO ? "ESMTP" : "SMTP"); 938 TAILQ_FOREACH(rcpt, &s->tx->rcpts, entry) { 939 log_info("%016"PRIx64" smtp envelope " 940 "evpid=%016"PRIx64" from=<%s%s%s> to=<%s%s%s>", 941 s->id, 942 rcpt->evpid, 943 s->tx->evp.sender.user, 944 s->tx->evp.sender.user[0] == '\0' ? "" : "@", 945 s->tx->evp.sender.domain, 946 rcpt->maddr.user, 947 rcpt->maddr.user[0] == '\0' ? "" : "@", 948 rcpt->maddr.domain); 949 } 950 smtp_tx_free(s->tx); 951 s->mailcount++; 952 smtp_enter_state(s, STATE_HELO); 953 return; 954 955 case IMSG_SMTP_AUTHENTICATE: 956 m_msg(&m, imsg); 957 m_get_id(&m, &reqid); 958 m_get_int(&m, &success); 959 m_end(&m); 960 961 s = tree_xpop(&wait_parent_auth, reqid); 962 strnvis(user, s->username, sizeof user, VIS_WHITE | VIS_SAFE); 963 if (success == LKA_OK) { 964 log_info("%016"PRIx64" smtp " 965 "authentication user=%s " 966 "result=ok", 967 s->id, user); 968 s->flags |= SF_AUTHENTICATED; 969 smtp_report_link_auth(s, user, "pass"); 970 smtp_reply(s, "235 %s Authentication succeeded", 971 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 972 } 973 else if (success == LKA_PERMFAIL) { 974 log_info("%016"PRIx64" smtp " 975 "authentication user=%s " 976 "result=permfail", 977 s->id, user); 978 smtp_report_link_auth(s, user, "fail"); 979 smtp_auth_failure_pause(s); 980 return; 981 } 982 else if (success == LKA_TEMPFAIL) { 983 log_info("%016"PRIx64" smtp " 984 "authentication user=%s " 985 "result=tempfail", 986 s->id, user); 987 smtp_report_link_auth(s, user, "error"); 988 smtp_reply(s, "421 %s Temporary failure", 989 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 990 } 991 else 992 fatalx("bad lka response"); 993 994 smtp_enter_state(s, STATE_HELO); 995 return; 996 997 case IMSG_FILTER_SMTP_PROTOCOL: 998 m_msg(&m, imsg); 999 m_get_id(&m, &reqid); 1000 m_get_int(&m, &filter_response); 1001 if (filter_response != FILTER_PROCEED && 1002 filter_response != FILTER_JUNK) 1003 m_get_string(&m, &filter_param); 1004 else 1005 filter_param = NULL; 1006 m_end(&m); 1007 1008 s = tree_xpop(&wait_filters, reqid); 1009 1010 switch (filter_response) { 1011 case FILTER_REJECT: 1012 case FILTER_DISCONNECT: 1013 if (!valid_smtp_response(filter_param) || 1014 (filter_param[0] != '4' && filter_param[0] != '5')) 1015 filter_param = "421 Internal server error"; 1016 if (!strncmp(filter_param, "421", 3)) 1017 filter_response = FILTER_DISCONNECT; 1018 1019 smtp_report_filter_response(s, s->filter_phase, 1020 filter_response, filter_param); 1021 1022 smtp_reply(s, "%s", filter_param); 1023 1024 if (filter_response == FILTER_DISCONNECT) 1025 smtp_enter_state(s, STATE_QUIT); 1026 else if (s->filter_phase == FILTER_COMMIT) 1027 smtp_proceed_rollback(s, NULL); 1028 break; 1029 1030 1031 case FILTER_JUNK: 1032 if (s->tx) 1033 s->tx->junk = 1; 1034 else 1035 s->junk = 1; 1036 /* fallthrough */ 1037 1038 case FILTER_PROCEED: 1039 filter_param = s->filter_param; 1040 /* fallthrough */ 1041 1042 case FILTER_REWRITE: 1043 smtp_report_filter_response(s, s->filter_phase, 1044 filter_response, 1045 filter_param == s->filter_param ? NULL : filter_param); 1046 if (s->filter_phase == FILTER_CONNECT) { 1047 smtp_proceed_connected(s); 1048 return; 1049 } 1050 for (i = 0; i < nitems(commands); ++i) 1051 if (commands[i].filter_phase == s->filter_phase) { 1052 if (filter_response == FILTER_REWRITE) 1053 if (!commands[i].check(s, filter_param)) 1054 break; 1055 commands[i].proceed(s, filter_param); 1056 break; 1057 } 1058 break; 1059 } 1060 return; 1061 } 1062 1063 log_warnx("smtp_session_imsg: unexpected %s imsg", 1064 imsg_to_str(imsg->hdr.type)); 1065 fatalx(NULL); 1066 } 1067 1068 static void 1069 smtp_tls_verified(struct smtp_session *s) 1070 { 1071 X509 *x; 1072 1073 x = SSL_get_peer_certificate(io_tls(s->io)); 1074 if (x) { 1075 log_info("%016"PRIx64" smtp " 1076 "client-cert-check result=\"%s\"", 1077 s->id, 1078 (s->flags & SF_VERIFIED) ? "success" : "failure"); 1079 X509_free(x); 1080 } 1081 1082 if (s->listener->flags & F_SMTPS) { 1083 stat_increment("smtp.smtps", 1); 1084 io_set_write(s->io); 1085 smtp_send_banner(s); 1086 } 1087 else { 1088 stat_increment("smtp.tls", 1); 1089 smtp_enter_state(s, STATE_HELO); 1090 } 1091 } 1092 1093 static void 1094 smtp_io(struct io *io, int evt, void *arg) 1095 { 1096 struct smtp_session *s = arg; 1097 char *line; 1098 size_t len; 1099 int eom; 1100 1101 log_trace(TRACE_IO, "smtp: %p: %s %s", s, io_strevent(evt), 1102 io_strio(io)); 1103 1104 switch (evt) { 1105 1106 case IO_TLSREADY: 1107 log_info("%016"PRIx64" smtp tls ciphers=%s", 1108 s->id, ssl_to_text(io_tls(s->io))); 1109 1110 smtp_report_link_tls(s, ssl_to_text(io_tls(s->io))); 1111 1112 s->flags |= SF_SECURE; 1113 s->helo[0] = '\0'; 1114 1115 smtp_cert_verify(s); 1116 break; 1117 1118 case IO_DATAIN: 1119 nextline: 1120 line = io_getline(s->io, &len); 1121 if ((line == NULL && io_datalen(s->io) >= SMTP_LINE_MAX) || 1122 (line && len >= SMTP_LINE_MAX)) { 1123 s->flags |= SF_BADINPUT; 1124 smtp_reply(s, "500 %s Line too long", 1125 esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_STATUS)); 1126 smtp_enter_state(s, STATE_QUIT); 1127 io_set_write(io); 1128 return; 1129 } 1130 1131 /* No complete line received */ 1132 if (line == NULL) 1133 return; 1134 1135 /* Message body */ 1136 eom = 0; 1137 if (s->state == STATE_BODY) { 1138 if (strcmp(line, ".")) { 1139 s->tx->datain += strlen(line) + 1; 1140 if (s->tx->datain > env->sc_maxsize) 1141 s->tx->error = TX_ERROR_SIZE; 1142 } 1143 eom = (s->tx->filter == NULL) ? 1144 smtp_tx_dataline(s->tx, line) : 1145 smtp_tx_filtered_dataline(s->tx, line); 1146 if (eom == 0) 1147 goto nextline; 1148 } 1149 1150 /* Pipelining not supported */ 1151 if (io_datalen(s->io)) { 1152 s->flags |= SF_BADINPUT; 1153 smtp_reply(s, "500 %s %s: Pipelining not supported", 1154 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1155 esc_description(ESC_INVALID_COMMAND)); 1156 smtp_enter_state(s, STATE_QUIT); 1157 io_set_write(io); 1158 return; 1159 } 1160 1161 if (eom) { 1162 io_set_write(io); 1163 if (s->tx->filter == NULL) 1164 smtp_tx_eom(s->tx); 1165 return; 1166 } 1167 1168 /* Must be a command */ 1169 if (strlcpy(s->cmd, line, sizeof(s->cmd)) >= sizeof(s->cmd)) { 1170 s->flags |= SF_BADINPUT; 1171 smtp_reply(s, "500 %s Command line too long", 1172 esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_STATUS)); 1173 smtp_enter_state(s, STATE_QUIT); 1174 io_set_write(io); 1175 return; 1176 } 1177 io_set_write(io); 1178 smtp_command(s, line); 1179 break; 1180 1181 case IO_LOWAT: 1182 if (s->state == STATE_QUIT) { 1183 log_info("%016"PRIx64" smtp disconnected " 1184 "reason=quit", 1185 s->id); 1186 smtp_free(s, "done"); 1187 break; 1188 } 1189 1190 /* Wait for the client to start tls */ 1191 if (s->state == STATE_TLS) { 1192 smtp_cert_init(s); 1193 break; 1194 } 1195 1196 io_set_read(io); 1197 break; 1198 1199 case IO_TIMEOUT: 1200 log_info("%016"PRIx64" smtp disconnected " 1201 "reason=timeout", 1202 s->id); 1203 smtp_report_timeout(s); 1204 smtp_free(s, "timeout"); 1205 break; 1206 1207 case IO_DISCONNECTED: 1208 log_info("%016"PRIx64" smtp disconnected " 1209 "reason=disconnect", 1210 s->id); 1211 smtp_free(s, "disconnected"); 1212 break; 1213 1214 case IO_ERROR: 1215 log_info("%016"PRIx64" smtp disconnected " 1216 "reason=\"io-error: %s\"", 1217 s->id, io_error(io)); 1218 smtp_free(s, "IO error"); 1219 break; 1220 1221 default: 1222 fatalx("smtp_io()"); 1223 } 1224 } 1225 1226 static void 1227 smtp_command(struct smtp_session *s, char *line) 1228 { 1229 char *args; 1230 int cmd, i; 1231 1232 log_trace(TRACE_SMTP, "smtp: %p: <<< %s", s, line); 1233 1234 /* 1235 * These states are special. 1236 */ 1237 if (s->state == STATE_AUTH_INIT) { 1238 smtp_report_protocol_client(s, "********"); 1239 smtp_rfc4954_auth_plain(s, line); 1240 return; 1241 } 1242 if (s->state == STATE_AUTH_USERNAME || s->state == STATE_AUTH_PASSWORD) { 1243 smtp_report_protocol_client(s, "********"); 1244 smtp_rfc4954_auth_login(s, line); 1245 return; 1246 } 1247 1248 if (s->state == STATE_HELO && strncasecmp(line, "AUTH PLAIN ", 11) == 0) 1249 smtp_report_protocol_client(s, "AUTH PLAIN ********"); 1250 else 1251 smtp_report_protocol_client(s, line); 1252 1253 1254 /* 1255 * Unlike other commands, "mail from" and "rcpt to" contain a 1256 * space in the command name. 1257 */ 1258 if (strncasecmp("mail from:", line, 10) == 0 || 1259 strncasecmp("rcpt to:", line, 8) == 0) 1260 args = strchr(line, ':'); 1261 else 1262 args = strchr(line, ' '); 1263 1264 if (args) { 1265 *args++ = '\0'; 1266 while (isspace((unsigned char)*args)) 1267 args++; 1268 } 1269 1270 cmd = -1; 1271 for (i = 0; commands[i].code != -1; i++) 1272 if (!strcasecmp(line, commands[i].cmd)) { 1273 cmd = commands[i].code; 1274 break; 1275 } 1276 1277 s->last_cmd = cmd; 1278 switch (cmd) { 1279 /* 1280 * INIT 1281 */ 1282 case CMD_HELO: 1283 if (!smtp_check_helo(s, args)) 1284 break; 1285 smtp_filter_phase(FILTER_HELO, s, args); 1286 break; 1287 1288 case CMD_EHLO: 1289 if (!smtp_check_ehlo(s, args)) 1290 break; 1291 smtp_filter_phase(FILTER_EHLO, s, args); 1292 break; 1293 1294 /* 1295 * SETUP 1296 */ 1297 case CMD_STARTTLS: 1298 if (!smtp_check_starttls(s, args)) 1299 break; 1300 1301 smtp_filter_phase(FILTER_STARTTLS, s, NULL); 1302 break; 1303 1304 case CMD_AUTH: 1305 if (!smtp_check_auth(s, args)) 1306 break; 1307 smtp_filter_phase(FILTER_AUTH, s, args); 1308 break; 1309 1310 case CMD_MAIL_FROM: 1311 if (!smtp_check_mail_from(s, args)) 1312 break; 1313 smtp_filter_phase(FILTER_MAIL_FROM, s, args); 1314 break; 1315 1316 /* 1317 * TRANSACTION 1318 */ 1319 case CMD_RCPT_TO: 1320 if (!smtp_check_rcpt_to(s, args)) 1321 break; 1322 smtp_filter_phase(FILTER_RCPT_TO, s, args); 1323 break; 1324 1325 case CMD_RSET: 1326 if (!smtp_check_rset(s, args)) 1327 break; 1328 smtp_filter_phase(FILTER_RSET, s, NULL); 1329 break; 1330 1331 case CMD_DATA: 1332 if (!smtp_check_data(s, args)) 1333 break; 1334 smtp_filter_phase(FILTER_DATA, s, NULL); 1335 break; 1336 1337 /* 1338 * ANY 1339 */ 1340 case CMD_QUIT: 1341 if (!smtp_check_noparam(s, args)) 1342 break; 1343 smtp_filter_phase(FILTER_QUIT, s, NULL); 1344 break; 1345 1346 case CMD_NOOP: 1347 if (!smtp_check_noparam(s, args)) 1348 break; 1349 smtp_filter_phase(FILTER_NOOP, s, NULL); 1350 break; 1351 1352 case CMD_HELP: 1353 if (!smtp_check_noparam(s, args)) 1354 break; 1355 smtp_proceed_help(s, NULL); 1356 break; 1357 1358 case CMD_WIZ: 1359 if (!smtp_check_noparam(s, args)) 1360 break; 1361 smtp_proceed_wiz(s, NULL); 1362 break; 1363 1364 default: 1365 smtp_reply(s, "500 %s %s: Command unrecognized", 1366 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1367 esc_description(ESC_INVALID_COMMAND)); 1368 break; 1369 } 1370 } 1371 1372 static int 1373 smtp_check_rset(struct smtp_session *s, const char *args) 1374 { 1375 if (!smtp_check_noparam(s, args)) 1376 return 0; 1377 1378 if (s->helo[0] == '\0') { 1379 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1380 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1381 esc_description(ESC_INVALID_COMMAND)); 1382 return 0; 1383 } 1384 return 1; 1385 } 1386 1387 static int 1388 smtp_check_helo(struct smtp_session *s, const char *args) 1389 { 1390 if (!s->banner_sent) { 1391 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1392 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1393 esc_description(ESC_INVALID_COMMAND)); 1394 return 0; 1395 } 1396 1397 if (s->helo[0]) { 1398 smtp_reply(s, "503 %s %s: Already identified", 1399 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1400 esc_description(ESC_INVALID_COMMAND)); 1401 return 0; 1402 } 1403 1404 if (args == NULL) { 1405 smtp_reply(s, "501 %s %s: HELO requires domain name", 1406 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1407 esc_description(ESC_INVALID_COMMAND)); 1408 return 0; 1409 } 1410 1411 if (!valid_domainpart(args)) { 1412 smtp_reply(s, "501 %s %s: Invalid domain name", 1413 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1414 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1415 return 0; 1416 } 1417 1418 return 1; 1419 } 1420 1421 static int 1422 smtp_check_ehlo(struct smtp_session *s, const char *args) 1423 { 1424 if (!s->banner_sent) { 1425 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1426 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1427 esc_description(ESC_INVALID_COMMAND)); 1428 return 0; 1429 } 1430 1431 if (s->helo[0]) { 1432 smtp_reply(s, "503 %s %s: Already identified", 1433 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1434 esc_description(ESC_INVALID_COMMAND)); 1435 return 0; 1436 } 1437 1438 if (args == NULL) { 1439 smtp_reply(s, "501 %s %s: EHLO requires domain name", 1440 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1441 esc_description(ESC_INVALID_COMMAND)); 1442 return 0; 1443 } 1444 1445 if (!valid_domainpart(args)) { 1446 smtp_reply(s, "501 %s %s: Invalid domain name", 1447 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1448 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1449 return 0; 1450 } 1451 1452 return 1; 1453 } 1454 1455 static int 1456 smtp_check_auth(struct smtp_session *s, const char *args) 1457 { 1458 if (s->helo[0] == '\0' || s->tx) { 1459 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1460 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1461 esc_description(ESC_INVALID_COMMAND)); 1462 return 0; 1463 } 1464 1465 if (s->flags & SF_AUTHENTICATED) { 1466 smtp_reply(s, "503 %s %s: Already authenticated", 1467 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1468 esc_description(ESC_INVALID_COMMAND)); 1469 return 0; 1470 } 1471 1472 if (!ADVERTISE_AUTH(s)) { 1473 smtp_reply(s, "503 %s %s: Command not supported", 1474 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1475 esc_description(ESC_INVALID_COMMAND)); 1476 return 0; 1477 } 1478 1479 if (args == NULL) { 1480 smtp_reply(s, "501 %s %s: No parameters given", 1481 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1482 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1483 return 0; 1484 } 1485 1486 return 1; 1487 } 1488 1489 static int 1490 smtp_check_starttls(struct smtp_session *s, const char *args) 1491 { 1492 if (s->helo[0] == '\0' || s->tx) { 1493 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1494 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1495 esc_description(ESC_INVALID_COMMAND)); 1496 return 0; 1497 } 1498 1499 if (!(s->listener->flags & F_STARTTLS)) { 1500 smtp_reply(s, "503 %s %s: Command not supported", 1501 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1502 esc_description(ESC_INVALID_COMMAND)); 1503 return 0; 1504 } 1505 1506 if (s->flags & SF_SECURE) { 1507 smtp_reply(s, "503 %s %s: Channel already secured", 1508 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1509 esc_description(ESC_INVALID_COMMAND)); 1510 return 0; 1511 } 1512 1513 if (args != NULL) { 1514 smtp_reply(s, "501 %s %s: No parameters allowed", 1515 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1516 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1517 return 0; 1518 } 1519 1520 return 1; 1521 } 1522 1523 static int 1524 smtp_check_mail_from(struct smtp_session *s, const char *args) 1525 { 1526 char *copy; 1527 char tmp[SMTP_LINE_MAX]; 1528 struct mailaddr sender; 1529 1530 (void)strlcpy(tmp, args, sizeof tmp); 1531 copy = tmp; 1532 1533 if (s->helo[0] == '\0' || s->tx) { 1534 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1535 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1536 esc_description(ESC_INVALID_COMMAND)); 1537 return 0; 1538 } 1539 1540 if (s->listener->flags & F_STARTTLS_REQUIRE && 1541 !(s->flags & SF_SECURE)) { 1542 smtp_reply(s, 1543 "530 %s %s: Must issue a STARTTLS command first", 1544 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1545 esc_description(ESC_INVALID_COMMAND)); 1546 return 0; 1547 } 1548 1549 if (s->listener->flags & F_AUTH_REQUIRE && 1550 !(s->flags & SF_AUTHENTICATED)) { 1551 smtp_reply(s, 1552 "530 %s %s: Must issue an AUTH command first", 1553 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1554 esc_description(ESC_INVALID_COMMAND)); 1555 return 0; 1556 } 1557 1558 if (s->mailcount >= env->sc_session_max_mails) { 1559 /* we can pretend we had too many recipients */ 1560 smtp_reply(s, "452 %s %s: Too many messages sent", 1561 esc_code(ESC_STATUS_TEMPFAIL, ESC_TOO_MANY_RECIPIENTS), 1562 esc_description(ESC_TOO_MANY_RECIPIENTS)); 1563 return 0; 1564 } 1565 1566 if (smtp_mailaddr(&sender, copy, 1, ©, 1567 s->smtpname) == 0) { 1568 smtp_reply(s, "553 %s Sender address syntax error", 1569 esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_ADDRESS_STATUS)); 1570 return 0; 1571 } 1572 1573 return 1; 1574 } 1575 1576 static int 1577 smtp_check_rcpt_to(struct smtp_session *s, const char *args) 1578 { 1579 char *copy; 1580 char tmp[SMTP_LINE_MAX]; 1581 1582 (void)strlcpy(tmp, args, sizeof tmp); 1583 copy = tmp; 1584 1585 if (s->tx == NULL) { 1586 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1587 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1588 esc_description(ESC_INVALID_COMMAND)); 1589 return 0; 1590 } 1591 1592 if (s->tx->rcptcount >= env->sc_session_max_rcpt) { 1593 smtp_reply(s->tx->session, "451 %s %s: Too many recipients", 1594 esc_code(ESC_STATUS_TEMPFAIL, ESC_TOO_MANY_RECIPIENTS), 1595 esc_description(ESC_TOO_MANY_RECIPIENTS)); 1596 return 0; 1597 } 1598 1599 if (smtp_mailaddr(&s->tx->evp.rcpt, copy, 0, ©, 1600 s->tx->session->smtpname) == 0) { 1601 smtp_reply(s->tx->session, 1602 "501 %s Recipient address syntax error", 1603 esc_code(ESC_STATUS_PERMFAIL, 1604 ESC_BAD_DESTINATION_MAILBOX_ADDRESS_SYNTAX)); 1605 return 0; 1606 } 1607 1608 return 1; 1609 } 1610 1611 static int 1612 smtp_check_data(struct smtp_session *s, const char *args) 1613 { 1614 if (!smtp_check_noparam(s, args)) 1615 return 0; 1616 1617 if (s->tx == NULL) { 1618 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1619 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1620 esc_description(ESC_INVALID_COMMAND)); 1621 return 0; 1622 } 1623 1624 if (s->tx->rcptcount == 0) { 1625 smtp_reply(s, "503 %s %s: No recipient specified", 1626 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1627 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1628 return 0; 1629 } 1630 1631 return 1; 1632 } 1633 1634 static int 1635 smtp_check_noparam(struct smtp_session *s, const char *args) 1636 { 1637 if (args != NULL) { 1638 smtp_reply(s, "500 %s %s: command does not accept arguments.", 1639 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1640 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1641 return 0; 1642 } 1643 return 1; 1644 } 1645 1646 static void 1647 smtp_query_filters(enum filter_phase phase, struct smtp_session *s, const char *args) 1648 { 1649 m_create(p_lka, IMSG_FILTER_SMTP_PROTOCOL, 0, 0, -1); 1650 m_add_id(p_lka, s->id); 1651 m_add_int(p_lka, phase); 1652 m_add_string(p_lka, args); 1653 m_close(p_lka); 1654 tree_xset(&wait_filters, s->id, s); 1655 } 1656 1657 static void 1658 smtp_filter_begin(struct smtp_session *s) 1659 { 1660 if (!SESSION_FILTERED(s)) 1661 return; 1662 1663 m_create(p_lka, IMSG_FILTER_SMTP_BEGIN, 0, 0, -1); 1664 m_add_id(p_lka, s->id); 1665 m_add_string(p_lka, s->listener->filter_name); 1666 m_close(p_lka); 1667 } 1668 1669 static void 1670 smtp_filter_end(struct smtp_session *s) 1671 { 1672 if (!SESSION_FILTERED(s)) 1673 return; 1674 1675 m_create(p_lka, IMSG_FILTER_SMTP_END, 0, 0, -1); 1676 m_add_id(p_lka, s->id); 1677 m_close(p_lka); 1678 } 1679 1680 static void 1681 smtp_filter_data_begin(struct smtp_session *s) 1682 { 1683 if (!SESSION_FILTERED(s)) 1684 return; 1685 1686 m_create(p_lka, IMSG_FILTER_SMTP_DATA_BEGIN, 0, 0, -1); 1687 m_add_id(p_lka, s->id); 1688 m_close(p_lka); 1689 tree_xset(&wait_filter_fd, s->id, s); 1690 } 1691 1692 static void 1693 smtp_filter_data_end(struct smtp_session *s) 1694 { 1695 if (!SESSION_FILTERED(s)) 1696 return; 1697 1698 if (s->tx->filter == NULL) 1699 return; 1700 1701 io_free(s->tx->filter); 1702 s->tx->filter = NULL; 1703 1704 m_create(p_lka, IMSG_FILTER_SMTP_DATA_END, 0, 0, -1); 1705 m_add_id(p_lka, s->id); 1706 m_close(p_lka); 1707 } 1708 1709 static void 1710 smtp_filter_phase(enum filter_phase phase, struct smtp_session *s, const char *param) 1711 { 1712 uint8_t i; 1713 1714 s->filter_phase = phase; 1715 s->filter_param = param; 1716 1717 if (SESSION_FILTERED(s)) { 1718 smtp_query_filters(phase, s, param ? param : ""); 1719 return; 1720 } 1721 1722 if (s->filter_phase == FILTER_CONNECT) { 1723 smtp_proceed_connected(s); 1724 return; 1725 } 1726 1727 for (i = 0; i < nitems(commands); ++i) 1728 if (commands[i].filter_phase == s->filter_phase) { 1729 commands[i].proceed(s, param); 1730 break; 1731 } 1732 } 1733 1734 static void 1735 smtp_proceed_rset(struct smtp_session *s, const char *args) 1736 { 1737 smtp_reply(s, "250 %s Reset state", 1738 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 1739 1740 if (s->tx) { 1741 if (s->tx->msgid) 1742 smtp_tx_rollback(s->tx); 1743 smtp_tx_free(s->tx); 1744 } 1745 } 1746 1747 static void 1748 smtp_proceed_helo(struct smtp_session *s, const char *args) 1749 { 1750 (void)strlcpy(s->helo, args, sizeof(s->helo)); 1751 s->flags &= SF_SECURE | SF_AUTHENTICATED | SF_VERIFIED; 1752 1753 smtp_report_link_identify(s, "HELO", s->helo); 1754 1755 smtp_enter_state(s, STATE_HELO); 1756 1757 smtp_reply(s, "250 %s Hello %s %s%s%s, pleased to meet you", 1758 s->smtpname, 1759 s->helo, 1760 s->ss.ss_family == AF_INET6 ? "" : "[", 1761 ss_to_text(&s->ss), 1762 s->ss.ss_family == AF_INET6 ? "" : "]"); 1763 } 1764 1765 static void 1766 smtp_proceed_ehlo(struct smtp_session *s, const char *args) 1767 { 1768 (void)strlcpy(s->helo, args, sizeof(s->helo)); 1769 s->flags &= SF_SECURE | SF_AUTHENTICATED | SF_VERIFIED; 1770 s->flags |= SF_EHLO; 1771 s->flags |= SF_8BITMIME; 1772 1773 smtp_report_link_identify(s, "EHLO", s->helo); 1774 1775 smtp_enter_state(s, STATE_HELO); 1776 smtp_reply(s, "250-%s Hello %s %s%s%s, pleased to meet you", 1777 s->smtpname, 1778 s->helo, 1779 s->ss.ss_family == AF_INET6 ? "" : "[", 1780 ss_to_text(&s->ss), 1781 s->ss.ss_family == AF_INET6 ? "" : "]"); 1782 1783 smtp_reply(s, "250-8BITMIME"); 1784 smtp_reply(s, "250-ENHANCEDSTATUSCODES"); 1785 smtp_reply(s, "250-SIZE %zu", env->sc_maxsize); 1786 if (ADVERTISE_EXT_DSN(s)) 1787 smtp_reply(s, "250-DSN"); 1788 if (ADVERTISE_TLS(s)) 1789 smtp_reply(s, "250-STARTTLS"); 1790 if (ADVERTISE_AUTH(s)) 1791 smtp_reply(s, "250-AUTH PLAIN LOGIN"); 1792 smtp_reply(s, "250 HELP"); 1793 } 1794 1795 static void 1796 smtp_proceed_auth(struct smtp_session *s, const char *args) 1797 { 1798 char tmp[SMTP_LINE_MAX]; 1799 char *eom, *method; 1800 1801 (void)strlcpy(tmp, args, sizeof tmp); 1802 1803 method = tmp; 1804 eom = strchr(tmp, ' '); 1805 if (eom == NULL) 1806 eom = strchr(tmp, '\t'); 1807 if (eom != NULL) 1808 *eom++ = '\0'; 1809 if (strcasecmp(method, "PLAIN") == 0) 1810 smtp_rfc4954_auth_plain(s, eom); 1811 else if (strcasecmp(method, "LOGIN") == 0) 1812 smtp_rfc4954_auth_login(s, eom); 1813 else 1814 smtp_reply(s, "504 %s %s: AUTH method \"%s\" not supported", 1815 esc_code(ESC_STATUS_PERMFAIL, ESC_SECURITY_FEATURES_NOT_SUPPORTED), 1816 esc_description(ESC_SECURITY_FEATURES_NOT_SUPPORTED), 1817 method); 1818 } 1819 1820 static void 1821 smtp_proceed_starttls(struct smtp_session *s, const char *args) 1822 { 1823 smtp_reply(s, "220 %s Ready to start TLS", 1824 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 1825 smtp_enter_state(s, STATE_TLS); 1826 } 1827 1828 static void 1829 smtp_proceed_mail_from(struct smtp_session *s, const char *args) 1830 { 1831 char *copy; 1832 char tmp[SMTP_LINE_MAX]; 1833 1834 (void)strlcpy(tmp, args, sizeof tmp); 1835 copy = tmp; 1836 1837 if (!smtp_tx(s)) { 1838 smtp_reply(s, "421 %s Temporary Error", 1839 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 1840 smtp_enter_state(s, STATE_QUIT); 1841 return; 1842 } 1843 1844 if (smtp_mailaddr(&s->tx->evp.sender, copy, 1, ©, 1845 s->smtpname) == 0) { 1846 smtp_reply(s, "553 %s Sender address syntax error", 1847 esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_ADDRESS_STATUS)); 1848 smtp_tx_free(s->tx); 1849 return; 1850 } 1851 1852 smtp_tx_mail_from(s->tx, args); 1853 } 1854 1855 static void 1856 smtp_proceed_rcpt_to(struct smtp_session *s, const char *args) 1857 { 1858 smtp_tx_rcpt_to(s->tx, args); 1859 } 1860 1861 static void 1862 smtp_proceed_data(struct smtp_session *s, const char *args) 1863 { 1864 smtp_tx_open_message(s->tx); 1865 } 1866 1867 static void 1868 smtp_proceed_quit(struct smtp_session *s, const char *args) 1869 { 1870 smtp_reply(s, "221 %s Bye", 1871 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 1872 smtp_enter_state(s, STATE_QUIT); 1873 } 1874 1875 static void 1876 smtp_proceed_noop(struct smtp_session *s, const char *args) 1877 { 1878 smtp_reply(s, "250 %s Ok", 1879 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 1880 } 1881 1882 static void 1883 smtp_proceed_help(struct smtp_session *s, const char *args) 1884 { 1885 const char *code = esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS); 1886 1887 smtp_reply(s, "214-%s This is " SMTPD_NAME, code); 1888 smtp_reply(s, "214-%s To report bugs in the implementation, " 1889 "please contact bugs@openbsd.org", code); 1890 smtp_reply(s, "214-%s with full details", code); 1891 smtp_reply(s, "214 %s End of HELP info", code); 1892 } 1893 1894 static void 1895 smtp_proceed_wiz(struct smtp_session *s, const char *args) 1896 { 1897 smtp_reply(s, "500 %s %s: this feature is not supported yet ;-)", 1898 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1899 esc_description(ESC_INVALID_COMMAND)); 1900 } 1901 1902 static void 1903 smtp_proceed_commit(struct smtp_session *s, const char *args) 1904 { 1905 smtp_message_end(s->tx); 1906 } 1907 1908 static void 1909 smtp_proceed_rollback(struct smtp_session *s, const char *args) 1910 { 1911 struct smtp_tx *tx; 1912 1913 tx = s->tx; 1914 1915 fclose(tx->ofile); 1916 tx->ofile = NULL; 1917 1918 smtp_tx_rollback(tx); 1919 smtp_tx_free(tx); 1920 smtp_enter_state(s, STATE_HELO); 1921 } 1922 1923 static void 1924 smtp_rfc4954_auth_plain(struct smtp_session *s, char *arg) 1925 { 1926 char buf[1024], *user, *pass; 1927 int len; 1928 1929 switch (s->state) { 1930 case STATE_HELO: 1931 if (arg == NULL) { 1932 smtp_enter_state(s, STATE_AUTH_INIT); 1933 smtp_reply(s, "334 "); 1934 return; 1935 } 1936 smtp_enter_state(s, STATE_AUTH_INIT); 1937 /* FALLTHROUGH */ 1938 1939 case STATE_AUTH_INIT: 1940 /* String is not NUL terminated, leave room. */ 1941 if ((len = base64_decode(arg, (unsigned char *)buf, 1942 sizeof(buf) - 1)) == -1) 1943 goto abort; 1944 /* buf is a byte string, NUL terminate. */ 1945 buf[len] = '\0'; 1946 1947 /* 1948 * Skip "foo" in "foo\0user\0pass", if present. 1949 */ 1950 user = memchr(buf, '\0', len); 1951 if (user == NULL || user >= buf + len - 2) 1952 goto abort; 1953 user++; /* skip NUL */ 1954 if (strlcpy(s->username, user, sizeof(s->username)) 1955 >= sizeof(s->username)) 1956 goto abort; 1957 1958 pass = memchr(user, '\0', len - (user - buf)); 1959 if (pass == NULL || pass >= buf + len - 2) 1960 goto abort; 1961 pass++; /* skip NUL */ 1962 1963 m_create(p_lka, IMSG_SMTP_AUTHENTICATE, 0, 0, -1); 1964 m_add_id(p_lka, s->id); 1965 m_add_string(p_lka, s->listener->authtable); 1966 m_add_string(p_lka, user); 1967 m_add_string(p_lka, pass); 1968 m_close(p_lka); 1969 tree_xset(&wait_parent_auth, s->id, s); 1970 return; 1971 1972 default: 1973 fatal("smtp_rfc4954_auth_plain: unknown state"); 1974 } 1975 1976 abort: 1977 smtp_reply(s, "501 %s %s: Syntax error", 1978 esc_code(ESC_STATUS_PERMFAIL, ESC_SYNTAX_ERROR), 1979 esc_description(ESC_SYNTAX_ERROR)); 1980 smtp_enter_state(s, STATE_HELO); 1981 } 1982 1983 static void 1984 smtp_rfc4954_auth_login(struct smtp_session *s, char *arg) 1985 { 1986 char buf[LINE_MAX]; 1987 1988 switch (s->state) { 1989 case STATE_HELO: 1990 smtp_enter_state(s, STATE_AUTH_USERNAME); 1991 if (arg != NULL && *arg != '\0') { 1992 smtp_rfc4954_auth_login(s, arg); 1993 return; 1994 } 1995 smtp_reply(s, "334 VXNlcm5hbWU6"); 1996 return; 1997 1998 case STATE_AUTH_USERNAME: 1999 memset(s->username, 0, sizeof(s->username)); 2000 if (base64_decode(arg, (unsigned char *)s->username, 2001 sizeof(s->username) - 1) == -1) 2002 goto abort; 2003 2004 smtp_enter_state(s, STATE_AUTH_PASSWORD); 2005 smtp_reply(s, "334 UGFzc3dvcmQ6"); 2006 return; 2007 2008 case STATE_AUTH_PASSWORD: 2009 memset(buf, 0, sizeof(buf)); 2010 if (base64_decode(arg, (unsigned char *)buf, 2011 sizeof(buf)-1) == -1) 2012 goto abort; 2013 2014 m_create(p_lka, IMSG_SMTP_AUTHENTICATE, 0, 0, -1); 2015 m_add_id(p_lka, s->id); 2016 m_add_string(p_lka, s->listener->authtable); 2017 m_add_string(p_lka, s->username); 2018 m_add_string(p_lka, buf); 2019 m_close(p_lka); 2020 tree_xset(&wait_parent_auth, s->id, s); 2021 return; 2022 2023 default: 2024 fatal("smtp_rfc4954_auth_login: unknown state"); 2025 } 2026 2027 abort: 2028 smtp_reply(s, "501 %s %s: Syntax error", 2029 esc_code(ESC_STATUS_PERMFAIL, ESC_SYNTAX_ERROR), 2030 esc_description(ESC_SYNTAX_ERROR)); 2031 smtp_enter_state(s, STATE_HELO); 2032 } 2033 2034 static void 2035 smtp_lookup_servername(struct smtp_session *s) 2036 { 2037 if (s->listener->hostnametable[0]) { 2038 m_create(p_lka, IMSG_SMTP_LOOKUP_HELO, 0, 0, -1); 2039 m_add_id(p_lka, s->id); 2040 m_add_string(p_lka, s->listener->hostnametable); 2041 m_add_sockaddr(p_lka, (struct sockaddr*)&s->listener->ss); 2042 m_close(p_lka); 2043 tree_xset(&wait_lka_helo, s->id, s); 2044 return; 2045 } 2046 2047 smtp_connected(s); 2048 } 2049 2050 static void 2051 smtp_connected(struct smtp_session *s) 2052 { 2053 smtp_enter_state(s, STATE_CONNECTED); 2054 2055 log_info("%016"PRIx64" smtp connected address=%s host=%s", 2056 s->id, ss_to_text(&s->ss), s->rdns); 2057 2058 smtp_filter_begin(s); 2059 2060 smtp_report_link_connect(s, s->rdns, s->fcrdns, &s->ss, 2061 &s->listener->ss); 2062 2063 smtp_filter_phase(FILTER_CONNECT, s, ss_to_text(&s->ss)); 2064 } 2065 2066 static void 2067 smtp_proceed_connected(struct smtp_session *s) 2068 { 2069 if (s->listener->flags & F_SMTPS) 2070 smtp_cert_init(s); 2071 else 2072 smtp_send_banner(s); 2073 } 2074 2075 static void 2076 smtp_send_banner(struct smtp_session *s) 2077 { 2078 smtp_reply(s, "220 %s ESMTP %s", s->smtpname, SMTPD_NAME); 2079 s->banner_sent = 1; 2080 smtp_report_link_greeting(s, s->smtpname); 2081 } 2082 2083 void 2084 smtp_enter_state(struct smtp_session *s, int newstate) 2085 { 2086 log_trace(TRACE_SMTP, "smtp: %p: %s -> %s", s, 2087 smtp_strstate(s->state), 2088 smtp_strstate(newstate)); 2089 2090 s->state = newstate; 2091 } 2092 2093 static void 2094 smtp_reply(struct smtp_session *s, char *fmt, ...) 2095 { 2096 va_list ap; 2097 int n; 2098 char buf[LINE_MAX*2], tmp[LINE_MAX*2]; 2099 2100 va_start(ap, fmt); 2101 n = vsnprintf(buf, sizeof buf, fmt, ap); 2102 va_end(ap); 2103 if (n < 0) 2104 fatalx("smtp_reply: response format error"); 2105 if (n < 4) 2106 fatalx("smtp_reply: response too short"); 2107 if (n >= (int)sizeof buf) { 2108 /* only first three bytes are used by SMTP logic, 2109 * so if _our_ reply does not fit entirely in the 2110 * buffer, it's ok to truncate. 2111 */ 2112 } 2113 2114 log_trace(TRACE_SMTP, "smtp: %p: >>> %s", s, buf); 2115 smtp_report_protocol_server(s, buf); 2116 2117 switch (buf[0]) { 2118 case '2': 2119 if (s->tx) { 2120 if (s->last_cmd == CMD_MAIL_FROM) { 2121 smtp_report_tx_begin(s, s->tx->msgid); 2122 smtp_report_tx_mail(s, s->tx->msgid, s->cmd + 10, 1); 2123 } 2124 else if (s->last_cmd == CMD_RCPT_TO) 2125 smtp_report_tx_rcpt(s, s->tx->msgid, s->cmd + 8, 1); 2126 } 2127 break; 2128 case '3': 2129 if (s->tx) { 2130 if (s->last_cmd == CMD_DATA) 2131 smtp_report_tx_data(s, s->tx->msgid, 1); 2132 } 2133 break; 2134 case '5': 2135 case '4': 2136 /* do not report smtp_tx_mail/smtp_tx_rcpt errors 2137 * if they happened outside of a transaction. 2138 */ 2139 if (s->tx) { 2140 if (s->last_cmd == CMD_MAIL_FROM) 2141 smtp_report_tx_mail(s, s->tx->msgid, 2142 s->cmd + 10, buf[0] == '4' ? -1 : 0); 2143 else if (s->last_cmd == CMD_RCPT_TO) 2144 smtp_report_tx_rcpt(s, 2145 s->tx->msgid, s->cmd + 8, buf[0] == '4' ? -1 : 0); 2146 else if (s->last_cmd == CMD_DATA && s->tx->rcptcount) 2147 smtp_report_tx_data(s, s->tx->msgid, 2148 buf[0] == '4' ? -1 : 0); 2149 } 2150 2151 if (s->flags & SF_BADINPUT) { 2152 log_info("%016"PRIx64" smtp " 2153 "bad-input result=\"%.*s\"", 2154 s->id, n, buf); 2155 } 2156 else if (s->state == STATE_AUTH_INIT) { 2157 log_info("%016"PRIx64" smtp " 2158 "failed-command " 2159 "command=\"AUTH PLAIN (...)\" result=\"%.*s\"", 2160 s->id, n, buf); 2161 } 2162 else if (s->state == STATE_AUTH_USERNAME) { 2163 log_info("%016"PRIx64" smtp " 2164 "failed-command " 2165 "command=\"AUTH LOGIN (username)\" result=\"%.*s\"", 2166 s->id, n, buf); 2167 } 2168 else if (s->state == STATE_AUTH_PASSWORD) { 2169 log_info("%016"PRIx64" smtp " 2170 "failed-command " 2171 "command=\"AUTH LOGIN (password)\" result=\"%.*s\"", 2172 s->id, n, buf); 2173 } 2174 else { 2175 strnvis(tmp, s->cmd, sizeof tmp, VIS_SAFE | VIS_CSTYLE); 2176 log_info("%016"PRIx64" smtp " 2177 "failed-command command=\"%s\" " 2178 "result=\"%.*s\"", 2179 s->id, tmp, n, buf); 2180 } 2181 break; 2182 } 2183 2184 io_xprintf(s->io, "%s\r\n", buf); 2185 } 2186 2187 static void 2188 smtp_free(struct smtp_session *s, const char * reason) 2189 { 2190 if (s->tx) { 2191 if (s->tx->msgid) 2192 smtp_tx_rollback(s->tx); 2193 smtp_tx_free(s->tx); 2194 } 2195 2196 smtp_report_link_disconnect(s); 2197 smtp_filter_end(s); 2198 2199 if (s->flags & SF_SECURE && s->listener->flags & F_SMTPS) 2200 stat_decrement("smtp.smtps", 1); 2201 if (s->flags & SF_SECURE && s->listener->flags & F_STARTTLS) 2202 stat_decrement("smtp.tls", 1); 2203 2204 io_free(s->io); 2205 free(s); 2206 2207 smtp_collect(); 2208 } 2209 2210 static int 2211 smtp_mailaddr(struct mailaddr *maddr, char *line, int mailfrom, char **args, 2212 const char *domain) 2213 { 2214 char *p, *e; 2215 2216 if (line == NULL) 2217 return (0); 2218 2219 if (*line != '<') 2220 return (0); 2221 2222 e = strchr(line, '>'); 2223 if (e == NULL) 2224 return (0); 2225 *e++ = '\0'; 2226 while (*e == ' ') 2227 e++; 2228 *args = e; 2229 2230 if (!text_to_mailaddr(maddr, line + 1)) 2231 return (0); 2232 2233 p = strchr(maddr->user, ':'); 2234 if (p != NULL) { 2235 p++; 2236 memmove(maddr->user, p, strlen(p) + 1); 2237 } 2238 2239 /* accept empty return-path in MAIL FROM, required for bounces */ 2240 if (mailfrom && maddr->user[0] == '\0' && maddr->domain[0] == '\0') 2241 return (1); 2242 2243 /* no or invalid user-part, reject */ 2244 if (maddr->user[0] == '\0' || !valid_localpart(maddr->user)) 2245 return (0); 2246 2247 /* no domain part, local user */ 2248 if (maddr->domain[0] == '\0') { 2249 (void)strlcpy(maddr->domain, domain, 2250 sizeof(maddr->domain)); 2251 } 2252 2253 if (!valid_domainpart(maddr->domain)) 2254 return (0); 2255 2256 return (1); 2257 } 2258 2259 static void 2260 smtp_cert_init(struct smtp_session *s) 2261 { 2262 const char *name; 2263 int fallback; 2264 2265 if (s->listener->pki_name[0]) { 2266 name = s->listener->pki_name; 2267 fallback = 0; 2268 } 2269 else { 2270 name = s->smtpname; 2271 fallback = 1; 2272 } 2273 2274 if (cert_init(name, fallback, smtp_cert_init_cb, s)) 2275 tree_xset(&wait_ssl_init, s->id, s); 2276 } 2277 2278 static void 2279 smtp_cert_init_cb(void *arg, int status, const char *name, const void *cert, 2280 size_t cert_len) 2281 { 2282 struct smtp_session *s = arg; 2283 void *ssl, *ssl_ctx; 2284 2285 tree_pop(&wait_ssl_init, s->id); 2286 2287 if (status == CA_FAIL) { 2288 log_info("%016"PRIx64" smtp disconnected " 2289 "reason=ca-failure", 2290 s->id); 2291 smtp_free(s, "CA failure"); 2292 return; 2293 } 2294 2295 ssl_ctx = dict_get(env->sc_ssl_dict, name); 2296 ssl = ssl_smtp_init(ssl_ctx, s->listener->flags & F_TLS_VERIFY); 2297 io_set_read(s->io); 2298 io_start_tls(s->io, ssl); 2299 } 2300 2301 static void 2302 smtp_cert_verify(struct smtp_session *s) 2303 { 2304 const char *name; 2305 int fallback; 2306 2307 if (s->listener->ca_name[0]) { 2308 name = s->listener->ca_name; 2309 fallback = 0; 2310 } 2311 else { 2312 name = s->smtpname; 2313 fallback = 1; 2314 } 2315 2316 if (cert_verify(io_tls(s->io), name, fallback, smtp_cert_verify_cb, s)) { 2317 tree_xset(&wait_ssl_verify, s->id, s); 2318 io_pause(s->io, IO_IN); 2319 } 2320 } 2321 2322 static void 2323 smtp_cert_verify_cb(void *arg, int status) 2324 { 2325 struct smtp_session *s = arg; 2326 const char *reason = NULL; 2327 int resume; 2328 2329 resume = tree_pop(&wait_ssl_verify, s->id) != NULL; 2330 2331 switch (status) { 2332 case CERT_OK: 2333 reason = "cert-ok"; 2334 s->flags |= SF_VERIFIED; 2335 break; 2336 case CERT_NOCA: 2337 reason = "no-ca"; 2338 break; 2339 case CERT_NOCERT: 2340 reason = "no-client-cert"; 2341 break; 2342 case CERT_INVALID: 2343 reason = "cert-invalid"; 2344 break; 2345 default: 2346 reason = "cert-check-failed"; 2347 break; 2348 } 2349 2350 log_debug("smtp: %p: smtp_cert_verify_cb: %s", s, reason); 2351 2352 if (!(s->flags & SF_VERIFIED) && (s->listener->flags & F_TLS_VERIFY)) { 2353 log_info("%016"PRIx64" smtp disconnected " 2354 " reason=%s", s->id, 2355 reason); 2356 smtp_free(s, "SSL certificate check failed"); 2357 return; 2358 } 2359 2360 smtp_tls_verified(s); 2361 if (resume) 2362 io_resume(s->io, IO_IN); 2363 } 2364 2365 static void 2366 smtp_auth_failure_resume(int fd, short event, void *p) 2367 { 2368 struct smtp_session *s = p; 2369 2370 smtp_reply(s, "535 Authentication failed"); 2371 smtp_enter_state(s, STATE_HELO); 2372 } 2373 2374 static void 2375 smtp_auth_failure_pause(struct smtp_session *s) 2376 { 2377 struct timeval tv; 2378 2379 tv.tv_sec = 0; 2380 tv.tv_usec = arc4random_uniform(1000000); 2381 log_trace(TRACE_SMTP, "smtp: timing-attack protection triggered, " 2382 "will defer answer for %lu microseconds", tv.tv_usec); 2383 evtimer_set(&s->pause, smtp_auth_failure_resume, s); 2384 evtimer_add(&s->pause, &tv); 2385 } 2386 2387 static int 2388 smtp_tx(struct smtp_session *s) 2389 { 2390 struct smtp_tx *tx; 2391 2392 tx = calloc(1, sizeof(*tx)); 2393 if (tx == NULL) 2394 return 0; 2395 2396 TAILQ_INIT(&tx->rcpts); 2397 2398 s->tx = tx; 2399 tx->session = s; 2400 2401 /* setup the envelope */ 2402 tx->evp.ss = s->ss; 2403 (void)strlcpy(tx->evp.tag, s->listener->tag, sizeof(tx->evp.tag)); 2404 (void)strlcpy(tx->evp.smtpname, s->smtpname, sizeof(tx->evp.smtpname)); 2405 (void)strlcpy(tx->evp.hostname, s->rdns, sizeof tx->evp.hostname); 2406 (void)strlcpy(tx->evp.helo, s->helo, sizeof(tx->evp.helo)); 2407 (void)strlcpy(tx->evp.username, s->username, sizeof(tx->evp.username)); 2408 2409 if (s->flags & SF_BOUNCE) 2410 tx->evp.flags |= EF_BOUNCE; 2411 if (s->flags & SF_AUTHENTICATED) 2412 tx->evp.flags |= EF_AUTHENTICATED; 2413 2414 if ((tx->parser = rfc5322_parser_new()) == NULL) { 2415 free(tx); 2416 return 0; 2417 } 2418 2419 return 1; 2420 } 2421 2422 static void 2423 smtp_tx_free(struct smtp_tx *tx) 2424 { 2425 struct smtp_rcpt *rcpt; 2426 2427 rfc5322_free(tx->parser); 2428 2429 while ((rcpt = TAILQ_FIRST(&tx->rcpts))) { 2430 TAILQ_REMOVE(&tx->rcpts, rcpt, entry); 2431 free(rcpt); 2432 } 2433 2434 if (tx->ofile) 2435 fclose(tx->ofile); 2436 2437 tx->session->tx = NULL; 2438 2439 free(tx); 2440 } 2441 2442 static void 2443 smtp_tx_mail_from(struct smtp_tx *tx, const char *line) 2444 { 2445 char *opt; 2446 char *copy; 2447 char tmp[SMTP_LINE_MAX]; 2448 2449 (void)strlcpy(tmp, line, sizeof tmp); 2450 copy = tmp; 2451 2452 if (smtp_mailaddr(&tx->evp.sender, copy, 1, ©, 2453 tx->session->smtpname) == 0) { 2454 smtp_reply(tx->session, "553 %s Sender address syntax error", 2455 esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_ADDRESS_STATUS)); 2456 smtp_tx_free(tx); 2457 return; 2458 } 2459 2460 while ((opt = strsep(©, " "))) { 2461 if (*opt == '\0') 2462 continue; 2463 2464 if (strncasecmp(opt, "AUTH=", 5) == 0) 2465 log_debug("debug: smtp: AUTH in MAIL FROM command"); 2466 else if (strncasecmp(opt, "SIZE=", 5) == 0) 2467 log_debug("debug: smtp: SIZE in MAIL FROM command"); 2468 else if (strcasecmp(opt, "BODY=7BIT") == 0) 2469 /* XXX only for this transaction */ 2470 tx->session->flags &= ~SF_8BITMIME; 2471 else if (strcasecmp(opt, "BODY=8BITMIME") == 0) 2472 ; 2473 else if (ADVERTISE_EXT_DSN(tx->session) && strncasecmp(opt, "RET=", 4) == 0) { 2474 opt += 4; 2475 if (strcasecmp(opt, "HDRS") == 0) 2476 tx->evp.dsn_ret = DSN_RETHDRS; 2477 else if (strcasecmp(opt, "FULL") == 0) 2478 tx->evp.dsn_ret = DSN_RETFULL; 2479 } else if (ADVERTISE_EXT_DSN(tx->session) && strncasecmp(opt, "ENVID=", 6) == 0) { 2480 opt += 6; 2481 if (strlcpy(tx->evp.dsn_envid, opt, sizeof(tx->evp.dsn_envid)) 2482 >= sizeof(tx->evp.dsn_envid)) { 2483 smtp_reply(tx->session, 2484 "503 %s %s: option too large, truncated: %s", 2485 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 2486 esc_description(ESC_INVALID_COMMAND_ARGUMENTS), opt); 2487 smtp_tx_free(tx); 2488 return; 2489 } 2490 } else { 2491 smtp_reply(tx->session, "503 %s %s: Unsupported option %s", 2492 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 2493 esc_description(ESC_INVALID_COMMAND_ARGUMENTS), opt); 2494 smtp_tx_free(tx); 2495 return; 2496 } 2497 } 2498 2499 /* only check sendertable if defined and user has authenticated */ 2500 if (tx->session->flags & SF_AUTHENTICATED && 2501 tx->session->listener->sendertable[0]) { 2502 m_create(p_lka, IMSG_SMTP_CHECK_SENDER, 0, 0, -1); 2503 m_add_id(p_lka, tx->session->id); 2504 m_add_string(p_lka, tx->session->listener->sendertable); 2505 m_add_string(p_lka, tx->session->username); 2506 m_add_mailaddr(p_lka, &tx->evp.sender); 2507 m_close(p_lka); 2508 tree_xset(&wait_lka_mail, tx->session->id, tx->session); 2509 } 2510 else 2511 smtp_tx_create_message(tx); 2512 } 2513 2514 static void 2515 smtp_tx_create_message(struct smtp_tx *tx) 2516 { 2517 m_create(p_queue, IMSG_SMTP_MESSAGE_CREATE, 0, 0, -1); 2518 m_add_id(p_queue, tx->session->id); 2519 m_close(p_queue); 2520 tree_xset(&wait_queue_msg, tx->session->id, tx->session); 2521 } 2522 2523 static void 2524 smtp_tx_rcpt_to(struct smtp_tx *tx, const char *line) 2525 { 2526 char *opt, *p; 2527 char *copy; 2528 char tmp[SMTP_LINE_MAX]; 2529 2530 (void)strlcpy(tmp, line, sizeof tmp); 2531 copy = tmp; 2532 2533 if (tx->rcptcount >= env->sc_session_max_rcpt) { 2534 smtp_reply(tx->session, "451 %s %s: Too many recipients", 2535 esc_code(ESC_STATUS_TEMPFAIL, ESC_TOO_MANY_RECIPIENTS), 2536 esc_description(ESC_TOO_MANY_RECIPIENTS)); 2537 return; 2538 } 2539 2540 if (smtp_mailaddr(&tx->evp.rcpt, copy, 0, ©, 2541 tx->session->smtpname) == 0) { 2542 smtp_reply(tx->session, 2543 "501 %s Recipient address syntax error", 2544 esc_code(ESC_STATUS_PERMFAIL, 2545 ESC_BAD_DESTINATION_MAILBOX_ADDRESS_SYNTAX)); 2546 return; 2547 } 2548 2549 while ((opt = strsep(©, " "))) { 2550 if (*opt == '\0') 2551 continue; 2552 2553 if (ADVERTISE_EXT_DSN(tx->session) && strncasecmp(opt, "NOTIFY=", 7) == 0) { 2554 opt += 7; 2555 while ((p = strsep(&opt, ","))) { 2556 if (strcasecmp(p, "SUCCESS") == 0) 2557 tx->evp.dsn_notify |= DSN_SUCCESS; 2558 else if (strcasecmp(p, "FAILURE") == 0) 2559 tx->evp.dsn_notify |= DSN_FAILURE; 2560 else if (strcasecmp(p, "DELAY") == 0) 2561 tx->evp.dsn_notify |= DSN_DELAY; 2562 else if (strcasecmp(p, "NEVER") == 0) 2563 tx->evp.dsn_notify |= DSN_NEVER; 2564 } 2565 2566 if (tx->evp.dsn_notify & DSN_NEVER && 2567 tx->evp.dsn_notify & (DSN_SUCCESS | DSN_FAILURE | 2568 DSN_DELAY)) { 2569 smtp_reply(tx->session, 2570 "553 NOTIFY option NEVER cannot be" 2571 " combined with other options"); 2572 return; 2573 } 2574 } else if (ADVERTISE_EXT_DSN(tx->session) && strncasecmp(opt, "ORCPT=", 6) == 0) { 2575 opt += 6; 2576 2577 if (strncasecmp(opt, "rfc822;", 7) == 0) 2578 opt += 7; 2579 2580 if (!text_to_mailaddr(&tx->evp.dsn_orcpt, opt) || 2581 !valid_localpart(tx->evp.dsn_orcpt.user) || 2582 !valid_domainpart(tx->evp.dsn_orcpt.domain)) { 2583 smtp_reply(tx->session, 2584 "553 ORCPT address syntax error"); 2585 return; 2586 } 2587 } else { 2588 smtp_reply(tx->session, "503 Unsupported option %s", opt); 2589 return; 2590 } 2591 } 2592 2593 m_create(p_lka, IMSG_SMTP_EXPAND_RCPT, 0, 0, -1); 2594 m_add_id(p_lka, tx->session->id); 2595 m_add_envelope(p_lka, &tx->evp); 2596 m_close(p_lka); 2597 tree_xset(&wait_lka_rcpt, tx->session->id, tx->session); 2598 } 2599 2600 static void 2601 smtp_tx_open_message(struct smtp_tx *tx) 2602 { 2603 m_create(p_queue, IMSG_SMTP_MESSAGE_OPEN, 0, 0, -1); 2604 m_add_id(p_queue, tx->session->id); 2605 m_add_msgid(p_queue, tx->msgid); 2606 m_close(p_queue); 2607 tree_xset(&wait_queue_fd, tx->session->id, tx->session); 2608 } 2609 2610 static void 2611 smtp_tx_commit(struct smtp_tx *tx) 2612 { 2613 m_create(p_queue, IMSG_SMTP_MESSAGE_COMMIT, 0, 0, -1); 2614 m_add_id(p_queue, tx->session->id); 2615 m_add_msgid(p_queue, tx->msgid); 2616 m_close(p_queue); 2617 tree_xset(&wait_queue_commit, tx->session->id, tx->session); 2618 smtp_filter_data_end(tx->session); 2619 } 2620 2621 static void 2622 smtp_tx_rollback(struct smtp_tx *tx) 2623 { 2624 m_create(p_queue, IMSG_SMTP_MESSAGE_ROLLBACK, 0, 0, -1); 2625 m_add_msgid(p_queue, tx->msgid); 2626 m_close(p_queue); 2627 smtp_report_tx_rollback(tx->session, tx->msgid); 2628 smtp_report_tx_reset(tx->session, tx->msgid); 2629 smtp_filter_data_end(tx->session); 2630 } 2631 2632 static int 2633 smtp_tx_dataline(struct smtp_tx *tx, const char *line) 2634 { 2635 struct rfc5322_result res; 2636 int r; 2637 2638 log_trace(TRACE_SMTP, "<<< [MSG] %s", line); 2639 2640 if (!strcmp(line, ".")) { 2641 smtp_report_protocol_client(tx->session, "."); 2642 log_trace(TRACE_SMTP, "<<< [EOM]"); 2643 if (tx->error) 2644 return 1; 2645 line = NULL; 2646 } 2647 else { 2648 /* ignore data line if an error is set */ 2649 if (tx->error) 2650 return 0; 2651 2652 /* escape lines starting with a '.' */ 2653 if (line[0] == '.') 2654 line += 1; 2655 } 2656 2657 if (rfc5322_push(tx->parser, line) == -1) { 2658 log_warnx("failed to push dataline"); 2659 tx->error = TX_ERROR_INTERNAL; 2660 return 0; 2661 } 2662 2663 for(;;) { 2664 r = rfc5322_next(tx->parser, &res); 2665 switch (r) { 2666 case -1: 2667 if (errno == ENOMEM) 2668 tx->error = TX_ERROR_INTERNAL; 2669 else 2670 tx->error = TX_ERROR_MALFORMED; 2671 return 0; 2672 2673 case RFC5322_NONE: 2674 /* Need more data */ 2675 return 0; 2676 2677 case RFC5322_HEADER_START: 2678 /* ignore bcc */ 2679 if (!strcasecmp("Bcc", res.hdr)) 2680 continue; 2681 2682 if (!strcasecmp("To", res.hdr) || 2683 !strcasecmp("Cc", res.hdr) || 2684 !strcasecmp("From", res.hdr)) { 2685 rfc5322_unfold_header(tx->parser); 2686 continue; 2687 } 2688 2689 if (!strcasecmp("Received", res.hdr)) { 2690 if (++tx->rcvcount >= MAX_HOPS_COUNT) { 2691 log_warnx("warn: loop detected"); 2692 tx->error = TX_ERROR_LOOP; 2693 return 0; 2694 } 2695 } 2696 else if (!tx->has_date && !strcasecmp("Date", res.hdr)) 2697 tx->has_date = 1; 2698 else if (!tx->has_message_id && 2699 !strcasecmp("Message-Id", res.hdr)) 2700 tx->has_message_id = 1; 2701 2702 smtp_message_printf(tx, "%s:%s\n", res.hdr, res.value); 2703 break; 2704 2705 case RFC5322_HEADER_CONT: 2706 2707 if (!strcasecmp("Bcc", res.hdr) || 2708 !strcasecmp("To", res.hdr) || 2709 !strcasecmp("Cc", res.hdr) || 2710 !strcasecmp("From", res.hdr)) 2711 continue; 2712 2713 smtp_message_printf(tx, "%s\n", res.value); 2714 break; 2715 2716 case RFC5322_HEADER_END: 2717 if (!strcasecmp("To", res.hdr) || 2718 !strcasecmp("Cc", res.hdr) || 2719 !strcasecmp("From", res.hdr)) 2720 header_domain_append_callback(tx, res.hdr, 2721 res.value); 2722 break; 2723 2724 case RFC5322_END_OF_HEADERS: 2725 if (tx->session->listener->local || 2726 tx->session->listener->port == 587) { 2727 2728 if (!tx->has_date) { 2729 log_debug("debug: %p: adding Date", tx); 2730 smtp_message_printf(tx, "Date: %s\n", 2731 time_to_text(tx->time)); 2732 } 2733 2734 if (!tx->has_message_id) { 2735 log_debug("debug: %p: adding Message-ID", tx); 2736 smtp_message_printf(tx, 2737 "Message-ID: <%016"PRIx64"@%s>\n", 2738 generate_uid(), 2739 tx->session->listener->hostname); 2740 } 2741 } 2742 break; 2743 2744 case RFC5322_BODY_START: 2745 case RFC5322_BODY: 2746 smtp_message_printf(tx, "%s\n", res.value); 2747 break; 2748 2749 case RFC5322_END_OF_MESSAGE: 2750 return 1; 2751 2752 default: 2753 fatalx("%s", __func__); 2754 } 2755 } 2756 } 2757 2758 static int 2759 smtp_tx_filtered_dataline(struct smtp_tx *tx, const char *line) 2760 { 2761 if (!strcmp(line, ".")) 2762 line = NULL; 2763 else { 2764 /* ignore data line if an error is set */ 2765 if (tx->error) 2766 return 0; 2767 } 2768 io_printf(tx->filter, "%s\n", line ? line : "."); 2769 return line ? 0 : 1; 2770 } 2771 2772 static void 2773 smtp_tx_eom(struct smtp_tx *tx) 2774 { 2775 smtp_filter_phase(FILTER_COMMIT, tx->session, NULL); 2776 } 2777 2778 static int 2779 smtp_message_fd(struct smtp_tx *tx, int fd) 2780 { 2781 struct smtp_session *s; 2782 2783 s = tx->session; 2784 2785 log_debug("smtp: %p: message fd %d", s, fd); 2786 2787 if ((tx->ofile = fdopen(fd, "w")) == NULL) { 2788 close(fd); 2789 smtp_reply(s, "421 %s Temporary Error", 2790 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 2791 smtp_enter_state(s, STATE_QUIT); 2792 return 0; 2793 } 2794 return 1; 2795 } 2796 2797 static void 2798 filter_session_io(struct io *io, int evt, void *arg) 2799 { 2800 struct smtp_tx*tx = arg; 2801 char*line = NULL; 2802 ssize_t len; 2803 2804 log_trace(TRACE_IO, "filter session io (smtp): %p: %s %s", tx, io_strevent(evt), 2805 io_strio(io)); 2806 2807 switch (evt) { 2808 case IO_DATAIN: 2809 nextline: 2810 line = io_getline(tx->filter, &len); 2811 /* No complete line received */ 2812 if (line == NULL) 2813 return; 2814 2815 if (smtp_tx_dataline(tx, line)) { 2816 smtp_tx_eom(tx); 2817 return; 2818 } 2819 2820 goto nextline; 2821 } 2822 } 2823 2824 static void 2825 smtp_filter_fd(struct smtp_tx *tx, int fd) 2826 { 2827 struct smtp_session *s; 2828 2829 s = tx->session; 2830 2831 log_debug("smtp: %p: filter fd %d", s, fd); 2832 2833 tx->filter = io_new(); 2834 io_set_fd(tx->filter, fd); 2835 io_set_callback(tx->filter, filter_session_io, tx); 2836 } 2837 2838 static void 2839 smtp_message_begin(struct smtp_tx *tx) 2840 { 2841 struct smtp_session *s; 2842 X509 *x; 2843 int (*m_printf)(struct smtp_tx *, const char *, ...); 2844 2845 m_printf = smtp_message_printf; 2846 if (tx->filter) 2847 m_printf = smtp_filter_printf; 2848 2849 s = tx->session; 2850 2851 log_debug("smtp: %p: message begin", s); 2852 2853 smtp_reply(s, "354 Enter mail, end with \".\"" 2854 " on a line by itself"); 2855 2856 if (s->junk || (s->tx && s->tx->junk)) 2857 m_printf(tx, "X-Spam: Yes\n"); 2858 2859 m_printf(tx, "Received: "); 2860 if (!(s->listener->flags & F_MASK_SOURCE)) { 2861 m_printf(tx, "from %s (%s %s%s%s)", 2862 s->helo, 2863 s->rdns, 2864 s->ss.ss_family == AF_INET6 ? "" : "[", 2865 ss_to_text(&s->ss), 2866 s->ss.ss_family == AF_INET6 ? "" : "]"); 2867 } 2868 m_printf(tx, "\n\tby %s (%s) with %sSMTP%s%s id %08x", 2869 s->smtpname, 2870 SMTPD_NAME, 2871 s->flags & SF_EHLO ? "E" : "", 2872 s->flags & SF_SECURE ? "S" : "", 2873 s->flags & SF_AUTHENTICATED ? "A" : "", 2874 tx->msgid); 2875 2876 if (s->flags & SF_SECURE) { 2877 x = SSL_get_peer_certificate(io_tls(s->io)); 2878 m_printf(tx, " (%s:%s:%d:%s)", 2879 SSL_get_version(io_tls(s->io)), 2880 SSL_get_cipher_name(io_tls(s->io)), 2881 SSL_get_cipher_bits(io_tls(s->io), NULL), 2882 (s->flags & SF_VERIFIED) ? "YES" : (x ? "FAIL" : "NO")); 2883 X509_free(x); 2884 2885 if (s->listener->flags & F_RECEIVEDAUTH) { 2886 m_printf(tx, " auth=%s", 2887 s->username[0] ? "yes" : "no"); 2888 if (s->username[0]) 2889 m_printf(tx, " user=%s", s->username); 2890 } 2891 } 2892 2893 if (tx->rcptcount == 1) { 2894 m_printf(tx, "\n\tfor <%s@%s>", 2895 tx->evp.rcpt.user, 2896 tx->evp.rcpt.domain); 2897 } 2898 2899 m_printf(tx, ";\n\t%s\n", time_to_text(time(&tx->time))); 2900 2901 smtp_enter_state(s, STATE_BODY); 2902 } 2903 2904 static void 2905 smtp_message_end(struct smtp_tx *tx) 2906 { 2907 struct smtp_session *s; 2908 2909 s = tx->session; 2910 2911 log_debug("debug: %p: end of message, error=%d", s, tx->error); 2912 2913 fclose(tx->ofile); 2914 tx->ofile = NULL; 2915 2916 switch(tx->error) { 2917 case TX_OK: 2918 smtp_tx_commit(tx); 2919 return; 2920 2921 case TX_ERROR_SIZE: 2922 smtp_reply(s, "554 %s %s: Transaction failed, message too big", 2923 esc_code(ESC_STATUS_PERMFAIL, ESC_MESSAGE_TOO_BIG_FOR_SYSTEM), 2924 esc_description(ESC_MESSAGE_TOO_BIG_FOR_SYSTEM)); 2925 break; 2926 2927 case TX_ERROR_LOOP: 2928 smtp_reply(s, "500 %s %s: Loop detected", 2929 esc_code(ESC_STATUS_PERMFAIL, ESC_ROUTING_LOOP_DETECTED), 2930 esc_description(ESC_ROUTING_LOOP_DETECTED)); 2931 break; 2932 2933 case TX_ERROR_MALFORMED: 2934 smtp_reply(s, "550 %s %s: Message is not RFC 2822 compliant", 2935 esc_code(ESC_STATUS_PERMFAIL, ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED), 2936 esc_description(ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED)); 2937 break; 2938 2939 case TX_ERROR_IO: 2940 case TX_ERROR_RESOURCES: 2941 smtp_reply(s, "421 %s Temporary Error", 2942 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 2943 break; 2944 2945 default: 2946 /* fatal? */ 2947 smtp_reply(s, "421 Internal server error"); 2948 } 2949 2950 smtp_tx_rollback(tx); 2951 smtp_tx_free(tx); 2952 smtp_enter_state(s, STATE_HELO); 2953 } 2954 2955 static int 2956 smtp_filter_printf(struct smtp_tx *tx, const char *fmt, ...) 2957 { 2958 va_list ap; 2959 int len; 2960 2961 if (tx->error) 2962 return -1; 2963 2964 va_start(ap, fmt); 2965 len = io_vprintf(tx->filter, fmt, ap); 2966 va_end(ap); 2967 2968 if (len < 0) { 2969 log_warn("smtp-in: session %016"PRIx64": vfprintf", tx->session->id); 2970 tx->error = TX_ERROR_IO; 2971 } 2972 else 2973 tx->odatalen += len; 2974 2975 return len; 2976 } 2977 2978 static int 2979 smtp_message_printf(struct smtp_tx *tx, const char *fmt, ...) 2980 { 2981 va_list ap; 2982 int len; 2983 2984 if (tx->error) 2985 return -1; 2986 2987 va_start(ap, fmt); 2988 len = vfprintf(tx->ofile, fmt, ap); 2989 va_end(ap); 2990 2991 if (len == -1) { 2992 log_warn("smtp-in: session %016"PRIx64": vfprintf", tx->session->id); 2993 tx->error = TX_ERROR_IO; 2994 } 2995 else 2996 tx->odatalen += len; 2997 2998 return len; 2999 } 3000 3001 #define CASE(x) case x : return #x 3002 3003 const char * 3004 smtp_strstate(int state) 3005 { 3006 static char buf[32]; 3007 3008 switch (state) { 3009 CASE(STATE_NEW); 3010 CASE(STATE_CONNECTED); 3011 CASE(STATE_TLS); 3012 CASE(STATE_HELO); 3013 CASE(STATE_AUTH_INIT); 3014 CASE(STATE_AUTH_USERNAME); 3015 CASE(STATE_AUTH_PASSWORD); 3016 CASE(STATE_AUTH_FINALIZE); 3017 CASE(STATE_BODY); 3018 CASE(STATE_QUIT); 3019 default: 3020 (void)snprintf(buf, sizeof(buf), "STATE_??? (%d)", state); 3021 return (buf); 3022 } 3023 } 3024 3025 3026 static void 3027 smtp_report_link_connect(struct smtp_session *s, const char *rdns, int fcrdns, 3028 const struct sockaddr_storage *ss_src, 3029 const struct sockaddr_storage *ss_dest) 3030 { 3031 if (! SESSION_FILTERED(s)) 3032 return; 3033 3034 report_smtp_link_connect("smtp-in", s->id, rdns, fcrdns, ss_src, ss_dest); 3035 } 3036 3037 static void 3038 smtp_report_link_greeting(struct smtp_session *s, 3039 const char *domain) 3040 { 3041 if (! SESSION_FILTERED(s)) 3042 return; 3043 3044 report_smtp_link_greeting("smtp-in", s->id, domain); 3045 } 3046 3047 static void 3048 smtp_report_link_identify(struct smtp_session *s, const char *method, const char *identity) 3049 { 3050 if (! SESSION_FILTERED(s)) 3051 return; 3052 3053 report_smtp_link_identify("smtp-in", s->id, method, identity); 3054 } 3055 3056 static void 3057 smtp_report_link_tls(struct smtp_session *s, const char *ssl) 3058 { 3059 if (! SESSION_FILTERED(s)) 3060 return; 3061 3062 report_smtp_link_tls("smtp-in", s->id, ssl); 3063 } 3064 3065 static void 3066 smtp_report_link_disconnect(struct smtp_session *s) 3067 { 3068 if (! SESSION_FILTERED(s)) 3069 return; 3070 3071 report_smtp_link_disconnect("smtp-in", s->id); 3072 } 3073 3074 static void 3075 smtp_report_link_auth(struct smtp_session *s, const char *user, const char *result) 3076 { 3077 if (! SESSION_FILTERED(s)) 3078 return; 3079 3080 report_smtp_link_auth("smtp-in", s->id, user, result); 3081 } 3082 3083 static void 3084 smtp_report_tx_reset(struct smtp_session *s, uint32_t msgid) 3085 { 3086 if (! SESSION_FILTERED(s)) 3087 return; 3088 3089 report_smtp_tx_reset("smtp-in", s->id, msgid); 3090 } 3091 3092 static void 3093 smtp_report_tx_begin(struct smtp_session *s, uint32_t msgid) 3094 { 3095 if (! SESSION_FILTERED(s)) 3096 return; 3097 3098 report_smtp_tx_begin("smtp-in", s->id, msgid); 3099 } 3100 3101 static void 3102 smtp_report_tx_mail(struct smtp_session *s, uint32_t msgid, const char *address, int ok) 3103 { 3104 char mailaddr[SMTPD_MAXMAILADDRSIZE]; 3105 char *p; 3106 3107 if (! SESSION_FILTERED(s)) 3108 return; 3109 3110 if ((p = strchr(address, '<')) == NULL) 3111 return; 3112 (void)strlcpy(mailaddr, p + 1, sizeof mailaddr); 3113 if ((p = strchr(mailaddr, '>')) == NULL) 3114 return; 3115 *p = '\0'; 3116 3117 report_smtp_tx_mail("smtp-in", s->id, msgid, mailaddr, ok); 3118 } 3119 3120 static void 3121 smtp_report_tx_rcpt(struct smtp_session *s, uint32_t msgid, const char *address, int ok) 3122 { 3123 char mailaddr[SMTPD_MAXMAILADDRSIZE]; 3124 char *p; 3125 3126 if (! SESSION_FILTERED(s)) 3127 return; 3128 3129 if ((p = strchr(address, '<')) == NULL) 3130 return; 3131 (void)strlcpy(mailaddr, p + 1, sizeof mailaddr); 3132 if ((p = strchr(mailaddr, '>')) == NULL) 3133 return; 3134 *p = '\0'; 3135 3136 report_smtp_tx_rcpt("smtp-in", s->id, msgid, mailaddr, ok); 3137 } 3138 3139 static void 3140 smtp_report_tx_envelope(struct smtp_session *s, uint32_t msgid, uint64_t evpid) 3141 { 3142 if (! SESSION_FILTERED(s)) 3143 return; 3144 3145 report_smtp_tx_envelope("smtp-in", s->id, msgid, evpid); 3146 } 3147 3148 static void 3149 smtp_report_tx_data(struct smtp_session *s, uint32_t msgid, int ok) 3150 { 3151 if (! SESSION_FILTERED(s)) 3152 return; 3153 3154 report_smtp_tx_data("smtp-in", s->id, msgid, ok); 3155 } 3156 3157 static void 3158 smtp_report_tx_commit(struct smtp_session *s, uint32_t msgid, size_t msgsz) 3159 { 3160 if (! SESSION_FILTERED(s)) 3161 return; 3162 3163 report_smtp_tx_commit("smtp-in", s->id, msgid, msgsz); 3164 } 3165 3166 static void 3167 smtp_report_tx_rollback(struct smtp_session *s, uint32_t msgid) 3168 { 3169 if (! SESSION_FILTERED(s)) 3170 return; 3171 3172 report_smtp_tx_rollback("smtp-in", s->id, msgid); 3173 } 3174 3175 static void 3176 smtp_report_protocol_client(struct smtp_session *s, const char *command) 3177 { 3178 if (! SESSION_FILTERED(s)) 3179 return; 3180 3181 report_smtp_protocol_client("smtp-in", s->id, command); 3182 } 3183 3184 static void 3185 smtp_report_protocol_server(struct smtp_session *s, const char *response) 3186 { 3187 if (! SESSION_FILTERED(s)) 3188 return; 3189 3190 report_smtp_protocol_server("smtp-in", s->id, response); 3191 } 3192 3193 static void 3194 smtp_report_filter_response(struct smtp_session *s, int phase, int response, const char *param) 3195 { 3196 if (! SESSION_FILTERED(s)) 3197 return; 3198 3199 report_smtp_filter_response("smtp-in", s->id, phase, response, param); 3200 } 3201 3202 static void 3203 smtp_report_timeout(struct smtp_session *s) 3204 { 3205 if (! SESSION_FILTERED(s)) 3206 return; 3207 3208 report_smtp_timeout("smtp-in", s->id); 3209 } 3210