1 /* $OpenBSD: smtp_session.c,v 1.428 2020/12/21 11:44:07 martijn 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((unsigned char)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, 641 NI_NAMEREQD | NI_NUMERICSERV, 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 /* Strip trailing '\r' */ 1136 if (len && line[len - 1] == '\r') 1137 line[--len] = '\0'; 1138 1139 /* Message body */ 1140 eom = 0; 1141 if (s->state == STATE_BODY) { 1142 if (strcmp(line, ".")) { 1143 s->tx->datain += strlen(line) + 1; 1144 if (s->tx->datain > env->sc_maxsize) 1145 s->tx->error = TX_ERROR_SIZE; 1146 } 1147 eom = (s->tx->filter == NULL) ? 1148 smtp_tx_dataline(s->tx, line) : 1149 smtp_tx_filtered_dataline(s->tx, line); 1150 if (eom == 0) 1151 goto nextline; 1152 } 1153 1154 /* Pipelining not supported */ 1155 if (io_datalen(s->io)) { 1156 s->flags |= SF_BADINPUT; 1157 smtp_reply(s, "500 %s %s: Pipelining not supported", 1158 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1159 esc_description(ESC_INVALID_COMMAND)); 1160 smtp_enter_state(s, STATE_QUIT); 1161 io_set_write(io); 1162 return; 1163 } 1164 1165 if (eom) { 1166 io_set_write(io); 1167 if (s->tx->filter == NULL) 1168 smtp_tx_eom(s->tx); 1169 return; 1170 } 1171 1172 /* Must be a command */ 1173 if (strlcpy(s->cmd, line, sizeof(s->cmd)) >= sizeof(s->cmd)) { 1174 s->flags |= SF_BADINPUT; 1175 smtp_reply(s, "500 %s Command line too long", 1176 esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_STATUS)); 1177 smtp_enter_state(s, STATE_QUIT); 1178 io_set_write(io); 1179 return; 1180 } 1181 io_set_write(io); 1182 smtp_command(s, line); 1183 break; 1184 1185 case IO_LOWAT: 1186 if (s->state == STATE_QUIT) { 1187 log_info("%016"PRIx64" smtp disconnected " 1188 "reason=quit", 1189 s->id); 1190 smtp_free(s, "done"); 1191 break; 1192 } 1193 1194 /* Wait for the client to start tls */ 1195 if (s->state == STATE_TLS) { 1196 smtp_cert_init(s); 1197 break; 1198 } 1199 1200 io_set_read(io); 1201 break; 1202 1203 case IO_TIMEOUT: 1204 log_info("%016"PRIx64" smtp disconnected " 1205 "reason=timeout", 1206 s->id); 1207 smtp_report_timeout(s); 1208 smtp_free(s, "timeout"); 1209 break; 1210 1211 case IO_DISCONNECTED: 1212 log_info("%016"PRIx64" smtp disconnected " 1213 "reason=disconnect", 1214 s->id); 1215 smtp_free(s, "disconnected"); 1216 break; 1217 1218 case IO_ERROR: 1219 log_info("%016"PRIx64" smtp disconnected " 1220 "reason=\"io-error: %s\"", 1221 s->id, io_error(io)); 1222 smtp_free(s, "IO error"); 1223 break; 1224 1225 default: 1226 fatalx("smtp_io()"); 1227 } 1228 } 1229 1230 static void 1231 smtp_command(struct smtp_session *s, char *line) 1232 { 1233 char *args; 1234 int cmd, i; 1235 1236 log_trace(TRACE_SMTP, "smtp: %p: <<< %s", s, line); 1237 1238 /* 1239 * These states are special. 1240 */ 1241 if (s->state == STATE_AUTH_INIT) { 1242 smtp_report_protocol_client(s, "********"); 1243 smtp_rfc4954_auth_plain(s, line); 1244 return; 1245 } 1246 if (s->state == STATE_AUTH_USERNAME || s->state == STATE_AUTH_PASSWORD) { 1247 smtp_report_protocol_client(s, "********"); 1248 smtp_rfc4954_auth_login(s, line); 1249 return; 1250 } 1251 1252 if (s->state == STATE_HELO && strncasecmp(line, "AUTH PLAIN ", 11) == 0) 1253 smtp_report_protocol_client(s, "AUTH PLAIN ********"); 1254 else 1255 smtp_report_protocol_client(s, line); 1256 1257 1258 /* 1259 * Unlike other commands, "mail from" and "rcpt to" contain a 1260 * space in the command name. 1261 */ 1262 if (strncasecmp("mail from:", line, 10) == 0 || 1263 strncasecmp("rcpt to:", line, 8) == 0) 1264 args = strchr(line, ':'); 1265 else 1266 args = strchr(line, ' '); 1267 1268 if (args) { 1269 *args++ = '\0'; 1270 while (isspace((unsigned char)*args)) 1271 args++; 1272 } 1273 1274 cmd = -1; 1275 for (i = 0; commands[i].code != -1; i++) 1276 if (!strcasecmp(line, commands[i].cmd)) { 1277 cmd = commands[i].code; 1278 break; 1279 } 1280 1281 s->last_cmd = cmd; 1282 switch (cmd) { 1283 /* 1284 * INIT 1285 */ 1286 case CMD_HELO: 1287 if (!smtp_check_helo(s, args)) 1288 break; 1289 smtp_filter_phase(FILTER_HELO, s, args); 1290 break; 1291 1292 case CMD_EHLO: 1293 if (!smtp_check_ehlo(s, args)) 1294 break; 1295 smtp_filter_phase(FILTER_EHLO, s, args); 1296 break; 1297 1298 /* 1299 * SETUP 1300 */ 1301 case CMD_STARTTLS: 1302 if (!smtp_check_starttls(s, args)) 1303 break; 1304 1305 smtp_filter_phase(FILTER_STARTTLS, s, NULL); 1306 break; 1307 1308 case CMD_AUTH: 1309 if (!smtp_check_auth(s, args)) 1310 break; 1311 smtp_filter_phase(FILTER_AUTH, s, args); 1312 break; 1313 1314 case CMD_MAIL_FROM: 1315 if (!smtp_check_mail_from(s, args)) 1316 break; 1317 smtp_filter_phase(FILTER_MAIL_FROM, s, args); 1318 break; 1319 1320 /* 1321 * TRANSACTION 1322 */ 1323 case CMD_RCPT_TO: 1324 if (!smtp_check_rcpt_to(s, args)) 1325 break; 1326 smtp_filter_phase(FILTER_RCPT_TO, s, args); 1327 break; 1328 1329 case CMD_RSET: 1330 if (!smtp_check_rset(s, args)) 1331 break; 1332 smtp_filter_phase(FILTER_RSET, s, NULL); 1333 break; 1334 1335 case CMD_DATA: 1336 if (!smtp_check_data(s, args)) 1337 break; 1338 smtp_filter_phase(FILTER_DATA, s, NULL); 1339 break; 1340 1341 /* 1342 * ANY 1343 */ 1344 case CMD_QUIT: 1345 if (!smtp_check_noparam(s, args)) 1346 break; 1347 smtp_filter_phase(FILTER_QUIT, s, NULL); 1348 break; 1349 1350 case CMD_NOOP: 1351 if (!smtp_check_noparam(s, args)) 1352 break; 1353 smtp_filter_phase(FILTER_NOOP, s, NULL); 1354 break; 1355 1356 case CMD_HELP: 1357 if (!smtp_check_noparam(s, args)) 1358 break; 1359 smtp_proceed_help(s, NULL); 1360 break; 1361 1362 case CMD_WIZ: 1363 if (!smtp_check_noparam(s, args)) 1364 break; 1365 smtp_proceed_wiz(s, NULL); 1366 break; 1367 1368 default: 1369 smtp_reply(s, "500 %s %s: Command unrecognized", 1370 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1371 esc_description(ESC_INVALID_COMMAND)); 1372 break; 1373 } 1374 } 1375 1376 static int 1377 smtp_check_rset(struct smtp_session *s, const char *args) 1378 { 1379 if (!smtp_check_noparam(s, args)) 1380 return 0; 1381 1382 if (s->helo[0] == '\0') { 1383 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1384 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1385 esc_description(ESC_INVALID_COMMAND)); 1386 return 0; 1387 } 1388 return 1; 1389 } 1390 1391 static int 1392 smtp_check_helo(struct smtp_session *s, const char *args) 1393 { 1394 if (!s->banner_sent) { 1395 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1396 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1397 esc_description(ESC_INVALID_COMMAND)); 1398 return 0; 1399 } 1400 1401 if (s->helo[0]) { 1402 smtp_reply(s, "503 %s %s: Already identified", 1403 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1404 esc_description(ESC_INVALID_COMMAND)); 1405 return 0; 1406 } 1407 1408 if (args == NULL) { 1409 smtp_reply(s, "501 %s %s: HELO requires domain name", 1410 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1411 esc_description(ESC_INVALID_COMMAND)); 1412 return 0; 1413 } 1414 1415 if (!valid_domainpart(args)) { 1416 smtp_reply(s, "501 %s %s: Invalid domain name", 1417 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1418 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1419 return 0; 1420 } 1421 1422 return 1; 1423 } 1424 1425 static int 1426 smtp_check_ehlo(struct smtp_session *s, const char *args) 1427 { 1428 if (!s->banner_sent) { 1429 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1430 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1431 esc_description(ESC_INVALID_COMMAND)); 1432 return 0; 1433 } 1434 1435 if (s->helo[0]) { 1436 smtp_reply(s, "503 %s %s: Already identified", 1437 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1438 esc_description(ESC_INVALID_COMMAND)); 1439 return 0; 1440 } 1441 1442 if (args == NULL) { 1443 smtp_reply(s, "501 %s %s: EHLO requires domain name", 1444 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1445 esc_description(ESC_INVALID_COMMAND)); 1446 return 0; 1447 } 1448 1449 if (!valid_domainpart(args)) { 1450 smtp_reply(s, "501 %s %s: Invalid domain name", 1451 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1452 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1453 return 0; 1454 } 1455 1456 return 1; 1457 } 1458 1459 static int 1460 smtp_check_auth(struct smtp_session *s, const char *args) 1461 { 1462 if (s->helo[0] == '\0' || s->tx) { 1463 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1464 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1465 esc_description(ESC_INVALID_COMMAND)); 1466 return 0; 1467 } 1468 1469 if (s->flags & SF_AUTHENTICATED) { 1470 smtp_reply(s, "503 %s %s: Already authenticated", 1471 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1472 esc_description(ESC_INVALID_COMMAND)); 1473 return 0; 1474 } 1475 1476 if (!ADVERTISE_AUTH(s)) { 1477 smtp_reply(s, "503 %s %s: Command not supported", 1478 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1479 esc_description(ESC_INVALID_COMMAND)); 1480 return 0; 1481 } 1482 1483 if (args == NULL) { 1484 smtp_reply(s, "501 %s %s: No parameters given", 1485 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1486 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1487 return 0; 1488 } 1489 1490 return 1; 1491 } 1492 1493 static int 1494 smtp_check_starttls(struct smtp_session *s, const char *args) 1495 { 1496 if (s->helo[0] == '\0' || s->tx) { 1497 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1498 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1499 esc_description(ESC_INVALID_COMMAND)); 1500 return 0; 1501 } 1502 1503 if (!(s->listener->flags & F_STARTTLS)) { 1504 smtp_reply(s, "503 %s %s: Command not supported", 1505 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1506 esc_description(ESC_INVALID_COMMAND)); 1507 return 0; 1508 } 1509 1510 if (s->flags & SF_SECURE) { 1511 smtp_reply(s, "503 %s %s: Channel already secured", 1512 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1513 esc_description(ESC_INVALID_COMMAND)); 1514 return 0; 1515 } 1516 1517 if (args != NULL) { 1518 smtp_reply(s, "501 %s %s: No parameters allowed", 1519 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1520 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1521 return 0; 1522 } 1523 1524 return 1; 1525 } 1526 1527 static int 1528 smtp_check_mail_from(struct smtp_session *s, const char *args) 1529 { 1530 char *copy; 1531 char tmp[SMTP_LINE_MAX]; 1532 struct mailaddr sender; 1533 1534 (void)strlcpy(tmp, args, sizeof tmp); 1535 copy = tmp; 1536 1537 if (s->helo[0] == '\0' || s->tx) { 1538 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1539 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1540 esc_description(ESC_INVALID_COMMAND)); 1541 return 0; 1542 } 1543 1544 if (s->listener->flags & F_STARTTLS_REQUIRE && 1545 !(s->flags & SF_SECURE)) { 1546 smtp_reply(s, 1547 "530 %s %s: Must issue a STARTTLS command first", 1548 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1549 esc_description(ESC_INVALID_COMMAND)); 1550 return 0; 1551 } 1552 1553 if (s->listener->flags & F_AUTH_REQUIRE && 1554 !(s->flags & SF_AUTHENTICATED)) { 1555 smtp_reply(s, 1556 "530 %s %s: Must issue an AUTH command first", 1557 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1558 esc_description(ESC_INVALID_COMMAND)); 1559 return 0; 1560 } 1561 1562 if (s->mailcount >= env->sc_session_max_mails) { 1563 /* we can pretend we had too many recipients */ 1564 smtp_reply(s, "452 %s %s: Too many messages sent", 1565 esc_code(ESC_STATUS_TEMPFAIL, ESC_TOO_MANY_RECIPIENTS), 1566 esc_description(ESC_TOO_MANY_RECIPIENTS)); 1567 return 0; 1568 } 1569 1570 if (smtp_mailaddr(&sender, copy, 1, ©, 1571 s->smtpname) == 0) { 1572 smtp_reply(s, "553 %s Sender address syntax error", 1573 esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_ADDRESS_STATUS)); 1574 return 0; 1575 } 1576 1577 return 1; 1578 } 1579 1580 static int 1581 smtp_check_rcpt_to(struct smtp_session *s, const char *args) 1582 { 1583 char *copy; 1584 char tmp[SMTP_LINE_MAX]; 1585 1586 (void)strlcpy(tmp, args, sizeof tmp); 1587 copy = tmp; 1588 1589 if (s->tx == NULL) { 1590 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1591 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1592 esc_description(ESC_INVALID_COMMAND)); 1593 return 0; 1594 } 1595 1596 if (s->tx->rcptcount >= env->sc_session_max_rcpt) { 1597 smtp_reply(s->tx->session, "451 %s %s: Too many recipients", 1598 esc_code(ESC_STATUS_TEMPFAIL, ESC_TOO_MANY_RECIPIENTS), 1599 esc_description(ESC_TOO_MANY_RECIPIENTS)); 1600 return 0; 1601 } 1602 1603 if (smtp_mailaddr(&s->tx->evp.rcpt, copy, 0, ©, 1604 s->tx->session->smtpname) == 0) { 1605 smtp_reply(s->tx->session, 1606 "501 %s Recipient address syntax error", 1607 esc_code(ESC_STATUS_PERMFAIL, 1608 ESC_BAD_DESTINATION_MAILBOX_ADDRESS_SYNTAX)); 1609 return 0; 1610 } 1611 1612 return 1; 1613 } 1614 1615 static int 1616 smtp_check_data(struct smtp_session *s, const char *args) 1617 { 1618 if (!smtp_check_noparam(s, args)) 1619 return 0; 1620 1621 if (s->tx == NULL) { 1622 smtp_reply(s, "503 %s %s: Command not allowed at this point.", 1623 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1624 esc_description(ESC_INVALID_COMMAND)); 1625 return 0; 1626 } 1627 1628 if (s->tx->rcptcount == 0) { 1629 smtp_reply(s, "503 %s %s: No recipient specified", 1630 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1631 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1632 return 0; 1633 } 1634 1635 return 1; 1636 } 1637 1638 static int 1639 smtp_check_noparam(struct smtp_session *s, const char *args) 1640 { 1641 if (args != NULL) { 1642 smtp_reply(s, "500 %s %s: command does not accept arguments.", 1643 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 1644 esc_description(ESC_INVALID_COMMAND_ARGUMENTS)); 1645 return 0; 1646 } 1647 return 1; 1648 } 1649 1650 static void 1651 smtp_query_filters(enum filter_phase phase, struct smtp_session *s, const char *args) 1652 { 1653 m_create(p_lka, IMSG_FILTER_SMTP_PROTOCOL, 0, 0, -1); 1654 m_add_id(p_lka, s->id); 1655 m_add_int(p_lka, phase); 1656 m_add_string(p_lka, args); 1657 m_close(p_lka); 1658 tree_xset(&wait_filters, s->id, s); 1659 } 1660 1661 static void 1662 smtp_filter_begin(struct smtp_session *s) 1663 { 1664 if (!SESSION_FILTERED(s)) 1665 return; 1666 1667 m_create(p_lka, IMSG_FILTER_SMTP_BEGIN, 0, 0, -1); 1668 m_add_id(p_lka, s->id); 1669 m_add_string(p_lka, s->listener->filter_name); 1670 m_close(p_lka); 1671 } 1672 1673 static void 1674 smtp_filter_end(struct smtp_session *s) 1675 { 1676 if (!SESSION_FILTERED(s)) 1677 return; 1678 1679 m_create(p_lka, IMSG_FILTER_SMTP_END, 0, 0, -1); 1680 m_add_id(p_lka, s->id); 1681 m_close(p_lka); 1682 } 1683 1684 static void 1685 smtp_filter_data_begin(struct smtp_session *s) 1686 { 1687 if (!SESSION_FILTERED(s)) 1688 return; 1689 1690 m_create(p_lka, IMSG_FILTER_SMTP_DATA_BEGIN, 0, 0, -1); 1691 m_add_id(p_lka, s->id); 1692 m_close(p_lka); 1693 tree_xset(&wait_filter_fd, s->id, s); 1694 } 1695 1696 static void 1697 smtp_filter_data_end(struct smtp_session *s) 1698 { 1699 if (!SESSION_FILTERED(s)) 1700 return; 1701 1702 if (s->tx->filter == NULL) 1703 return; 1704 1705 io_free(s->tx->filter); 1706 s->tx->filter = NULL; 1707 1708 m_create(p_lka, IMSG_FILTER_SMTP_DATA_END, 0, 0, -1); 1709 m_add_id(p_lka, s->id); 1710 m_close(p_lka); 1711 } 1712 1713 static void 1714 smtp_filter_phase(enum filter_phase phase, struct smtp_session *s, const char *param) 1715 { 1716 uint8_t i; 1717 1718 s->filter_phase = phase; 1719 s->filter_param = param; 1720 1721 if (SESSION_FILTERED(s)) { 1722 smtp_query_filters(phase, s, param ? param : ""); 1723 return; 1724 } 1725 1726 if (s->filter_phase == FILTER_CONNECT) { 1727 smtp_proceed_connected(s); 1728 return; 1729 } 1730 1731 for (i = 0; i < nitems(commands); ++i) 1732 if (commands[i].filter_phase == s->filter_phase) { 1733 commands[i].proceed(s, param); 1734 break; 1735 } 1736 } 1737 1738 static void 1739 smtp_proceed_rset(struct smtp_session *s, const char *args) 1740 { 1741 smtp_reply(s, "250 %s Reset state", 1742 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 1743 1744 if (s->tx) { 1745 if (s->tx->msgid) 1746 smtp_tx_rollback(s->tx); 1747 smtp_tx_free(s->tx); 1748 } 1749 } 1750 1751 static void 1752 smtp_proceed_helo(struct smtp_session *s, const char *args) 1753 { 1754 (void)strlcpy(s->helo, args, sizeof(s->helo)); 1755 s->flags &= SF_SECURE | SF_AUTHENTICATED | SF_VERIFIED; 1756 1757 smtp_report_link_identify(s, "HELO", s->helo); 1758 1759 smtp_enter_state(s, STATE_HELO); 1760 1761 smtp_reply(s, "250 %s Hello %s %s%s%s, pleased to meet you", 1762 s->smtpname, 1763 s->helo, 1764 s->ss.ss_family == AF_INET6 ? "" : "[", 1765 ss_to_text(&s->ss), 1766 s->ss.ss_family == AF_INET6 ? "" : "]"); 1767 } 1768 1769 static void 1770 smtp_proceed_ehlo(struct smtp_session *s, const char *args) 1771 { 1772 (void)strlcpy(s->helo, args, sizeof(s->helo)); 1773 s->flags &= SF_SECURE | SF_AUTHENTICATED | SF_VERIFIED; 1774 s->flags |= SF_EHLO; 1775 s->flags |= SF_8BITMIME; 1776 1777 smtp_report_link_identify(s, "EHLO", s->helo); 1778 1779 smtp_enter_state(s, STATE_HELO); 1780 smtp_reply(s, "250-%s Hello %s %s%s%s, pleased to meet you", 1781 s->smtpname, 1782 s->helo, 1783 s->ss.ss_family == AF_INET6 ? "" : "[", 1784 ss_to_text(&s->ss), 1785 s->ss.ss_family == AF_INET6 ? "" : "]"); 1786 1787 smtp_reply(s, "250-8BITMIME"); 1788 smtp_reply(s, "250-ENHANCEDSTATUSCODES"); 1789 smtp_reply(s, "250-SIZE %zu", env->sc_maxsize); 1790 if (ADVERTISE_EXT_DSN(s)) 1791 smtp_reply(s, "250-DSN"); 1792 if (ADVERTISE_TLS(s)) 1793 smtp_reply(s, "250-STARTTLS"); 1794 if (ADVERTISE_AUTH(s)) 1795 smtp_reply(s, "250-AUTH PLAIN LOGIN"); 1796 smtp_reply(s, "250 HELP"); 1797 } 1798 1799 static void 1800 smtp_proceed_auth(struct smtp_session *s, const char *args) 1801 { 1802 char tmp[SMTP_LINE_MAX]; 1803 char *eom, *method; 1804 1805 (void)strlcpy(tmp, args, sizeof tmp); 1806 1807 method = tmp; 1808 eom = strchr(tmp, ' '); 1809 if (eom == NULL) 1810 eom = strchr(tmp, '\t'); 1811 if (eom != NULL) 1812 *eom++ = '\0'; 1813 if (strcasecmp(method, "PLAIN") == 0) 1814 smtp_rfc4954_auth_plain(s, eom); 1815 else if (strcasecmp(method, "LOGIN") == 0) 1816 smtp_rfc4954_auth_login(s, eom); 1817 else 1818 smtp_reply(s, "504 %s %s: AUTH method \"%s\" not supported", 1819 esc_code(ESC_STATUS_PERMFAIL, ESC_SECURITY_FEATURES_NOT_SUPPORTED), 1820 esc_description(ESC_SECURITY_FEATURES_NOT_SUPPORTED), 1821 method); 1822 } 1823 1824 static void 1825 smtp_proceed_starttls(struct smtp_session *s, const char *args) 1826 { 1827 smtp_reply(s, "220 %s Ready to start TLS", 1828 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 1829 smtp_enter_state(s, STATE_TLS); 1830 } 1831 1832 static void 1833 smtp_proceed_mail_from(struct smtp_session *s, const char *args) 1834 { 1835 char *copy; 1836 char tmp[SMTP_LINE_MAX]; 1837 1838 (void)strlcpy(tmp, args, sizeof tmp); 1839 copy = tmp; 1840 1841 if (!smtp_tx(s)) { 1842 smtp_reply(s, "421 %s Temporary Error", 1843 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 1844 smtp_enter_state(s, STATE_QUIT); 1845 return; 1846 } 1847 1848 if (smtp_mailaddr(&s->tx->evp.sender, copy, 1, ©, 1849 s->smtpname) == 0) { 1850 smtp_reply(s, "553 %s Sender address syntax error", 1851 esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_ADDRESS_STATUS)); 1852 smtp_tx_free(s->tx); 1853 return; 1854 } 1855 1856 smtp_tx_mail_from(s->tx, args); 1857 } 1858 1859 static void 1860 smtp_proceed_rcpt_to(struct smtp_session *s, const char *args) 1861 { 1862 smtp_tx_rcpt_to(s->tx, args); 1863 } 1864 1865 static void 1866 smtp_proceed_data(struct smtp_session *s, const char *args) 1867 { 1868 smtp_tx_open_message(s->tx); 1869 } 1870 1871 static void 1872 smtp_proceed_quit(struct smtp_session *s, const char *args) 1873 { 1874 smtp_reply(s, "221 %s Bye", 1875 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 1876 smtp_enter_state(s, STATE_QUIT); 1877 } 1878 1879 static void 1880 smtp_proceed_noop(struct smtp_session *s, const char *args) 1881 { 1882 smtp_reply(s, "250 %s Ok", 1883 esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); 1884 } 1885 1886 static void 1887 smtp_proceed_help(struct smtp_session *s, const char *args) 1888 { 1889 const char *code = esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS); 1890 1891 smtp_reply(s, "214-%s This is " SMTPD_NAME, code); 1892 smtp_reply(s, "214-%s To report bugs in the implementation, " 1893 "please contact bugs@openbsd.org", code); 1894 smtp_reply(s, "214-%s with full details", code); 1895 smtp_reply(s, "214 %s End of HELP info", code); 1896 } 1897 1898 static void 1899 smtp_proceed_wiz(struct smtp_session *s, const char *args) 1900 { 1901 smtp_reply(s, "500 %s %s: this feature is not supported yet ;-)", 1902 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), 1903 esc_description(ESC_INVALID_COMMAND)); 1904 } 1905 1906 static void 1907 smtp_proceed_commit(struct smtp_session *s, const char *args) 1908 { 1909 smtp_message_end(s->tx); 1910 } 1911 1912 static void 1913 smtp_proceed_rollback(struct smtp_session *s, const char *args) 1914 { 1915 struct smtp_tx *tx; 1916 1917 tx = s->tx; 1918 1919 fclose(tx->ofile); 1920 tx->ofile = NULL; 1921 1922 smtp_tx_rollback(tx); 1923 smtp_tx_free(tx); 1924 smtp_enter_state(s, STATE_HELO); 1925 } 1926 1927 static void 1928 smtp_rfc4954_auth_plain(struct smtp_session *s, char *arg) 1929 { 1930 char buf[1024], *user, *pass; 1931 int len; 1932 1933 switch (s->state) { 1934 case STATE_HELO: 1935 if (arg == NULL) { 1936 smtp_enter_state(s, STATE_AUTH_INIT); 1937 smtp_reply(s, "334 "); 1938 return; 1939 } 1940 smtp_enter_state(s, STATE_AUTH_INIT); 1941 /* FALLTHROUGH */ 1942 1943 case STATE_AUTH_INIT: 1944 /* String is not NUL terminated, leave room. */ 1945 if ((len = base64_decode(arg, (unsigned char *)buf, 1946 sizeof(buf) - 1)) == -1) 1947 goto abort; 1948 /* buf is a byte string, NUL terminate. */ 1949 buf[len] = '\0'; 1950 1951 /* 1952 * Skip "foo" in "foo\0user\0pass", if present. 1953 */ 1954 user = memchr(buf, '\0', len); 1955 if (user == NULL || user >= buf + len - 2) 1956 goto abort; 1957 user++; /* skip NUL */ 1958 if (strlcpy(s->username, user, sizeof(s->username)) 1959 >= sizeof(s->username)) 1960 goto abort; 1961 1962 pass = memchr(user, '\0', len - (user - buf)); 1963 if (pass == NULL || pass >= buf + len - 2) 1964 goto abort; 1965 pass++; /* skip NUL */ 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, user); 1971 m_add_string(p_lka, pass); 1972 m_close(p_lka); 1973 tree_xset(&wait_parent_auth, s->id, s); 1974 return; 1975 1976 default: 1977 fatal("smtp_rfc4954_auth_plain: 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 void 1988 smtp_rfc4954_auth_login(struct smtp_session *s, char *arg) 1989 { 1990 char buf[LINE_MAX]; 1991 1992 switch (s->state) { 1993 case STATE_HELO: 1994 smtp_enter_state(s, STATE_AUTH_USERNAME); 1995 if (arg != NULL && *arg != '\0') { 1996 smtp_rfc4954_auth_login(s, arg); 1997 return; 1998 } 1999 smtp_reply(s, "334 VXNlcm5hbWU6"); 2000 return; 2001 2002 case STATE_AUTH_USERNAME: 2003 memset(s->username, 0, sizeof(s->username)); 2004 if (base64_decode(arg, (unsigned char *)s->username, 2005 sizeof(s->username) - 1) == -1) 2006 goto abort; 2007 2008 smtp_enter_state(s, STATE_AUTH_PASSWORD); 2009 smtp_reply(s, "334 UGFzc3dvcmQ6"); 2010 return; 2011 2012 case STATE_AUTH_PASSWORD: 2013 memset(buf, 0, sizeof(buf)); 2014 if (base64_decode(arg, (unsigned char *)buf, 2015 sizeof(buf)-1) == -1) 2016 goto abort; 2017 2018 m_create(p_lka, IMSG_SMTP_AUTHENTICATE, 0, 0, -1); 2019 m_add_id(p_lka, s->id); 2020 m_add_string(p_lka, s->listener->authtable); 2021 m_add_string(p_lka, s->username); 2022 m_add_string(p_lka, buf); 2023 m_close(p_lka); 2024 tree_xset(&wait_parent_auth, s->id, s); 2025 return; 2026 2027 default: 2028 fatal("smtp_rfc4954_auth_login: unknown state"); 2029 } 2030 2031 abort: 2032 smtp_reply(s, "501 %s %s: Syntax error", 2033 esc_code(ESC_STATUS_PERMFAIL, ESC_SYNTAX_ERROR), 2034 esc_description(ESC_SYNTAX_ERROR)); 2035 smtp_enter_state(s, STATE_HELO); 2036 } 2037 2038 static void 2039 smtp_lookup_servername(struct smtp_session *s) 2040 { 2041 if (s->listener->hostnametable[0]) { 2042 m_create(p_lka, IMSG_SMTP_LOOKUP_HELO, 0, 0, -1); 2043 m_add_id(p_lka, s->id); 2044 m_add_string(p_lka, s->listener->hostnametable); 2045 m_add_sockaddr(p_lka, (struct sockaddr*)&s->listener->ss); 2046 m_close(p_lka); 2047 tree_xset(&wait_lka_helo, s->id, s); 2048 return; 2049 } 2050 2051 smtp_connected(s); 2052 } 2053 2054 static void 2055 smtp_connected(struct smtp_session *s) 2056 { 2057 smtp_enter_state(s, STATE_CONNECTED); 2058 2059 log_info("%016"PRIx64" smtp connected address=%s host=%s", 2060 s->id, ss_to_text(&s->ss), s->rdns); 2061 2062 smtp_filter_begin(s); 2063 2064 smtp_report_link_connect(s, s->rdns, s->fcrdns, &s->ss, 2065 &s->listener->ss); 2066 2067 smtp_filter_phase(FILTER_CONNECT, s, ss_to_text(&s->ss)); 2068 } 2069 2070 static void 2071 smtp_proceed_connected(struct smtp_session *s) 2072 { 2073 if (s->listener->flags & F_SMTPS) 2074 smtp_cert_init(s); 2075 else 2076 smtp_send_banner(s); 2077 } 2078 2079 static void 2080 smtp_send_banner(struct smtp_session *s) 2081 { 2082 smtp_reply(s, "220 %s ESMTP %s", s->smtpname, SMTPD_NAME); 2083 s->banner_sent = 1; 2084 smtp_report_link_greeting(s, s->smtpname); 2085 } 2086 2087 void 2088 smtp_enter_state(struct smtp_session *s, int newstate) 2089 { 2090 log_trace(TRACE_SMTP, "smtp: %p: %s -> %s", s, 2091 smtp_strstate(s->state), 2092 smtp_strstate(newstate)); 2093 2094 s->state = newstate; 2095 } 2096 2097 static void 2098 smtp_reply(struct smtp_session *s, char *fmt, ...) 2099 { 2100 va_list ap; 2101 int n; 2102 char buf[LINE_MAX*2], tmp[LINE_MAX*2]; 2103 2104 va_start(ap, fmt); 2105 n = vsnprintf(buf, sizeof buf, fmt, ap); 2106 va_end(ap); 2107 if (n < 0) 2108 fatalx("smtp_reply: response format error"); 2109 if (n < 4) 2110 fatalx("smtp_reply: response too short"); 2111 if (n >= (int)sizeof buf) { 2112 /* only first three bytes are used by SMTP logic, 2113 * so if _our_ reply does not fit entirely in the 2114 * buffer, it's ok to truncate. 2115 */ 2116 } 2117 2118 log_trace(TRACE_SMTP, "smtp: %p: >>> %s", s, buf); 2119 smtp_report_protocol_server(s, buf); 2120 2121 switch (buf[0]) { 2122 case '2': 2123 if (s->tx) { 2124 if (s->last_cmd == CMD_MAIL_FROM) { 2125 smtp_report_tx_begin(s, s->tx->msgid); 2126 smtp_report_tx_mail(s, s->tx->msgid, s->cmd + 10, 1); 2127 } 2128 else if (s->last_cmd == CMD_RCPT_TO) 2129 smtp_report_tx_rcpt(s, s->tx->msgid, s->cmd + 8, 1); 2130 } 2131 break; 2132 case '3': 2133 if (s->tx) { 2134 if (s->last_cmd == CMD_DATA) 2135 smtp_report_tx_data(s, s->tx->msgid, 1); 2136 } 2137 break; 2138 case '5': 2139 case '4': 2140 /* do not report smtp_tx_mail/smtp_tx_rcpt errors 2141 * if they happened outside of a transaction. 2142 */ 2143 if (s->tx) { 2144 if (s->last_cmd == CMD_MAIL_FROM) 2145 smtp_report_tx_mail(s, s->tx->msgid, 2146 s->cmd + 10, buf[0] == '4' ? -1 : 0); 2147 else if (s->last_cmd == CMD_RCPT_TO) 2148 smtp_report_tx_rcpt(s, 2149 s->tx->msgid, s->cmd + 8, buf[0] == '4' ? -1 : 0); 2150 else if (s->last_cmd == CMD_DATA && s->tx->rcptcount) 2151 smtp_report_tx_data(s, s->tx->msgid, 2152 buf[0] == '4' ? -1 : 0); 2153 } 2154 2155 if (s->flags & SF_BADINPUT) { 2156 log_info("%016"PRIx64" smtp " 2157 "bad-input result=\"%.*s\"", 2158 s->id, n, buf); 2159 } 2160 else if (s->state == STATE_AUTH_INIT) { 2161 log_info("%016"PRIx64" smtp " 2162 "failed-command " 2163 "command=\"AUTH PLAIN (...)\" result=\"%.*s\"", 2164 s->id, n, buf); 2165 } 2166 else if (s->state == STATE_AUTH_USERNAME) { 2167 log_info("%016"PRIx64" smtp " 2168 "failed-command " 2169 "command=\"AUTH LOGIN (username)\" result=\"%.*s\"", 2170 s->id, n, buf); 2171 } 2172 else if (s->state == STATE_AUTH_PASSWORD) { 2173 log_info("%016"PRIx64" smtp " 2174 "failed-command " 2175 "command=\"AUTH LOGIN (password)\" result=\"%.*s\"", 2176 s->id, n, buf); 2177 } 2178 else { 2179 strnvis(tmp, s->cmd, sizeof tmp, VIS_SAFE | VIS_CSTYLE); 2180 log_info("%016"PRIx64" smtp " 2181 "failed-command command=\"%s\" " 2182 "result=\"%.*s\"", 2183 s->id, tmp, n, buf); 2184 } 2185 break; 2186 } 2187 2188 io_xprintf(s->io, "%s\r\n", buf); 2189 } 2190 2191 static void 2192 smtp_free(struct smtp_session *s, const char * reason) 2193 { 2194 if (s->tx) { 2195 if (s->tx->msgid) 2196 smtp_tx_rollback(s->tx); 2197 smtp_tx_free(s->tx); 2198 } 2199 2200 smtp_report_link_disconnect(s); 2201 smtp_filter_end(s); 2202 2203 if (s->flags & SF_SECURE && s->listener->flags & F_SMTPS) 2204 stat_decrement("smtp.smtps", 1); 2205 if (s->flags & SF_SECURE && s->listener->flags & F_STARTTLS) 2206 stat_decrement("smtp.tls", 1); 2207 2208 io_free(s->io); 2209 free(s); 2210 2211 smtp_collect(); 2212 } 2213 2214 static int 2215 smtp_mailaddr(struct mailaddr *maddr, char *line, int mailfrom, char **args, 2216 const char *domain) 2217 { 2218 char *p, *e; 2219 2220 if (line == NULL) 2221 return (0); 2222 2223 if (*line != '<') 2224 return (0); 2225 2226 e = strchr(line, '>'); 2227 if (e == NULL) 2228 return (0); 2229 *e++ = '\0'; 2230 while (*e == ' ') 2231 e++; 2232 *args = e; 2233 2234 if (!text_to_mailaddr(maddr, line + 1)) 2235 return (0); 2236 2237 p = strchr(maddr->user, ':'); 2238 if (p != NULL) { 2239 p++; 2240 memmove(maddr->user, p, strlen(p) + 1); 2241 } 2242 2243 /* accept empty return-path in MAIL FROM, required for bounces */ 2244 if (mailfrom && maddr->user[0] == '\0' && maddr->domain[0] == '\0') 2245 return (1); 2246 2247 /* no or invalid user-part, reject */ 2248 if (maddr->user[0] == '\0' || !valid_localpart(maddr->user)) 2249 return (0); 2250 2251 /* no domain part, local user */ 2252 if (maddr->domain[0] == '\0') { 2253 (void)strlcpy(maddr->domain, domain, 2254 sizeof(maddr->domain)); 2255 } 2256 2257 if (!valid_domainpart(maddr->domain)) 2258 return (0); 2259 2260 return (1); 2261 } 2262 2263 static void 2264 smtp_cert_init(struct smtp_session *s) 2265 { 2266 const char *name; 2267 int fallback; 2268 2269 if (s->listener->pki_name[0]) { 2270 name = s->listener->pki_name; 2271 fallback = 0; 2272 } 2273 else { 2274 name = s->smtpname; 2275 fallback = 1; 2276 } 2277 2278 if (cert_init(name, fallback, smtp_cert_init_cb, s)) 2279 tree_xset(&wait_ssl_init, s->id, s); 2280 } 2281 2282 static void 2283 smtp_cert_init_cb(void *arg, int status, const char *name, const void *cert, 2284 size_t cert_len) 2285 { 2286 struct smtp_session *s = arg; 2287 void *ssl, *ssl_ctx; 2288 2289 tree_pop(&wait_ssl_init, s->id); 2290 2291 if (status == CA_FAIL) { 2292 log_info("%016"PRIx64" smtp disconnected " 2293 "reason=ca-failure", 2294 s->id); 2295 smtp_free(s, "CA failure"); 2296 return; 2297 } 2298 2299 ssl_ctx = dict_get(env->sc_ssl_dict, name); 2300 ssl = ssl_smtp_init(ssl_ctx, s->listener->flags & F_TLS_VERIFY); 2301 io_set_read(s->io); 2302 io_start_tls(s->io, ssl); 2303 } 2304 2305 static void 2306 smtp_cert_verify(struct smtp_session *s) 2307 { 2308 const char *name; 2309 int fallback; 2310 2311 if (s->listener->ca_name[0]) { 2312 name = s->listener->ca_name; 2313 fallback = 0; 2314 } 2315 else { 2316 name = s->smtpname; 2317 fallback = 1; 2318 } 2319 2320 if (cert_verify(io_tls(s->io), name, fallback, smtp_cert_verify_cb, s)) { 2321 tree_xset(&wait_ssl_verify, s->id, s); 2322 io_pause(s->io, IO_IN); 2323 } 2324 } 2325 2326 static void 2327 smtp_cert_verify_cb(void *arg, int status) 2328 { 2329 struct smtp_session *s = arg; 2330 const char *reason = NULL; 2331 int resume; 2332 2333 resume = tree_pop(&wait_ssl_verify, s->id) != NULL; 2334 2335 switch (status) { 2336 case CERT_OK: 2337 reason = "cert-ok"; 2338 s->flags |= SF_VERIFIED; 2339 break; 2340 case CERT_NOCA: 2341 reason = "no-ca"; 2342 break; 2343 case CERT_NOCERT: 2344 reason = "no-client-cert"; 2345 break; 2346 case CERT_INVALID: 2347 reason = "cert-invalid"; 2348 break; 2349 default: 2350 reason = "cert-check-failed"; 2351 break; 2352 } 2353 2354 log_debug("smtp: %p: smtp_cert_verify_cb: %s", s, reason); 2355 2356 if (!(s->flags & SF_VERIFIED) && (s->listener->flags & F_TLS_VERIFY)) { 2357 log_info("%016"PRIx64" smtp disconnected " 2358 " reason=%s", s->id, 2359 reason); 2360 smtp_free(s, "SSL certificate check failed"); 2361 return; 2362 } 2363 2364 smtp_tls_verified(s); 2365 if (resume) 2366 io_resume(s->io, IO_IN); 2367 } 2368 2369 static void 2370 smtp_auth_failure_resume(int fd, short event, void *p) 2371 { 2372 struct smtp_session *s = p; 2373 2374 smtp_reply(s, "535 Authentication failed"); 2375 smtp_enter_state(s, STATE_HELO); 2376 } 2377 2378 static void 2379 smtp_auth_failure_pause(struct smtp_session *s) 2380 { 2381 struct timeval tv; 2382 2383 tv.tv_sec = 0; 2384 tv.tv_usec = arc4random_uniform(1000000); 2385 log_trace(TRACE_SMTP, "smtp: timing-attack protection triggered, " 2386 "will defer answer for %lu microseconds", tv.tv_usec); 2387 evtimer_set(&s->pause, smtp_auth_failure_resume, s); 2388 evtimer_add(&s->pause, &tv); 2389 } 2390 2391 static int 2392 smtp_tx(struct smtp_session *s) 2393 { 2394 struct smtp_tx *tx; 2395 2396 tx = calloc(1, sizeof(*tx)); 2397 if (tx == NULL) 2398 return 0; 2399 2400 TAILQ_INIT(&tx->rcpts); 2401 2402 s->tx = tx; 2403 tx->session = s; 2404 2405 /* setup the envelope */ 2406 tx->evp.ss = s->ss; 2407 (void)strlcpy(tx->evp.tag, s->listener->tag, sizeof(tx->evp.tag)); 2408 (void)strlcpy(tx->evp.smtpname, s->smtpname, sizeof(tx->evp.smtpname)); 2409 (void)strlcpy(tx->evp.hostname, s->rdns, sizeof tx->evp.hostname); 2410 (void)strlcpy(tx->evp.helo, s->helo, sizeof(tx->evp.helo)); 2411 (void)strlcpy(tx->evp.username, s->username, sizeof(tx->evp.username)); 2412 2413 if (s->flags & SF_BOUNCE) 2414 tx->evp.flags |= EF_BOUNCE; 2415 if (s->flags & SF_AUTHENTICATED) 2416 tx->evp.flags |= EF_AUTHENTICATED; 2417 2418 if ((tx->parser = rfc5322_parser_new()) == NULL) { 2419 free(tx); 2420 return 0; 2421 } 2422 2423 return 1; 2424 } 2425 2426 static void 2427 smtp_tx_free(struct smtp_tx *tx) 2428 { 2429 struct smtp_rcpt *rcpt; 2430 2431 rfc5322_free(tx->parser); 2432 2433 while ((rcpt = TAILQ_FIRST(&tx->rcpts))) { 2434 TAILQ_REMOVE(&tx->rcpts, rcpt, entry); 2435 free(rcpt); 2436 } 2437 2438 if (tx->ofile) 2439 fclose(tx->ofile); 2440 2441 tx->session->tx = NULL; 2442 2443 free(tx); 2444 } 2445 2446 static void 2447 smtp_tx_mail_from(struct smtp_tx *tx, const char *line) 2448 { 2449 char *opt; 2450 char *copy; 2451 char tmp[SMTP_LINE_MAX]; 2452 2453 (void)strlcpy(tmp, line, sizeof tmp); 2454 copy = tmp; 2455 2456 if (smtp_mailaddr(&tx->evp.sender, copy, 1, ©, 2457 tx->session->smtpname) == 0) { 2458 smtp_reply(tx->session, "553 %s Sender address syntax error", 2459 esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_ADDRESS_STATUS)); 2460 smtp_tx_free(tx); 2461 return; 2462 } 2463 2464 while ((opt = strsep(©, " "))) { 2465 if (*opt == '\0') 2466 continue; 2467 2468 if (strncasecmp(opt, "AUTH=", 5) == 0) 2469 log_debug("debug: smtp: AUTH in MAIL FROM command"); 2470 else if (strncasecmp(opt, "SIZE=", 5) == 0) 2471 log_debug("debug: smtp: SIZE in MAIL FROM command"); 2472 else if (strcasecmp(opt, "BODY=7BIT") == 0) 2473 /* XXX only for this transaction */ 2474 tx->session->flags &= ~SF_8BITMIME; 2475 else if (strcasecmp(opt, "BODY=8BITMIME") == 0) 2476 ; 2477 else if (ADVERTISE_EXT_DSN(tx->session) && strncasecmp(opt, "RET=", 4) == 0) { 2478 opt += 4; 2479 if (strcasecmp(opt, "HDRS") == 0) 2480 tx->evp.dsn_ret = DSN_RETHDRS; 2481 else if (strcasecmp(opt, "FULL") == 0) 2482 tx->evp.dsn_ret = DSN_RETFULL; 2483 } else if (ADVERTISE_EXT_DSN(tx->session) && strncasecmp(opt, "ENVID=", 6) == 0) { 2484 opt += 6; 2485 if (strlcpy(tx->evp.dsn_envid, opt, sizeof(tx->evp.dsn_envid)) 2486 >= sizeof(tx->evp.dsn_envid)) { 2487 smtp_reply(tx->session, 2488 "503 %s %s: option too large, truncated: %s", 2489 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 2490 esc_description(ESC_INVALID_COMMAND_ARGUMENTS), opt); 2491 smtp_tx_free(tx); 2492 return; 2493 } 2494 } else { 2495 smtp_reply(tx->session, "503 %s %s: Unsupported option %s", 2496 esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS), 2497 esc_description(ESC_INVALID_COMMAND_ARGUMENTS), opt); 2498 smtp_tx_free(tx); 2499 return; 2500 } 2501 } 2502 2503 /* only check sendertable if defined and user has authenticated */ 2504 if (tx->session->flags & SF_AUTHENTICATED && 2505 tx->session->listener->sendertable[0]) { 2506 m_create(p_lka, IMSG_SMTP_CHECK_SENDER, 0, 0, -1); 2507 m_add_id(p_lka, tx->session->id); 2508 m_add_string(p_lka, tx->session->listener->sendertable); 2509 m_add_string(p_lka, tx->session->username); 2510 m_add_mailaddr(p_lka, &tx->evp.sender); 2511 m_close(p_lka); 2512 tree_xset(&wait_lka_mail, tx->session->id, tx->session); 2513 } 2514 else 2515 smtp_tx_create_message(tx); 2516 } 2517 2518 static void 2519 smtp_tx_create_message(struct smtp_tx *tx) 2520 { 2521 m_create(p_queue, IMSG_SMTP_MESSAGE_CREATE, 0, 0, -1); 2522 m_add_id(p_queue, tx->session->id); 2523 m_close(p_queue); 2524 tree_xset(&wait_queue_msg, tx->session->id, tx->session); 2525 } 2526 2527 static void 2528 smtp_tx_rcpt_to(struct smtp_tx *tx, const char *line) 2529 { 2530 char *opt, *p; 2531 char *copy; 2532 char tmp[SMTP_LINE_MAX]; 2533 2534 (void)strlcpy(tmp, line, sizeof tmp); 2535 copy = tmp; 2536 2537 if (tx->rcptcount >= env->sc_session_max_rcpt) { 2538 smtp_reply(tx->session, "451 %s %s: Too many recipients", 2539 esc_code(ESC_STATUS_TEMPFAIL, ESC_TOO_MANY_RECIPIENTS), 2540 esc_description(ESC_TOO_MANY_RECIPIENTS)); 2541 return; 2542 } 2543 2544 if (smtp_mailaddr(&tx->evp.rcpt, copy, 0, ©, 2545 tx->session->smtpname) == 0) { 2546 smtp_reply(tx->session, 2547 "501 %s Recipient address syntax error", 2548 esc_code(ESC_STATUS_PERMFAIL, 2549 ESC_BAD_DESTINATION_MAILBOX_ADDRESS_SYNTAX)); 2550 return; 2551 } 2552 2553 while ((opt = strsep(©, " "))) { 2554 if (*opt == '\0') 2555 continue; 2556 2557 if (ADVERTISE_EXT_DSN(tx->session) && strncasecmp(opt, "NOTIFY=", 7) == 0) { 2558 opt += 7; 2559 while ((p = strsep(&opt, ","))) { 2560 if (strcasecmp(p, "SUCCESS") == 0) 2561 tx->evp.dsn_notify |= DSN_SUCCESS; 2562 else if (strcasecmp(p, "FAILURE") == 0) 2563 tx->evp.dsn_notify |= DSN_FAILURE; 2564 else if (strcasecmp(p, "DELAY") == 0) 2565 tx->evp.dsn_notify |= DSN_DELAY; 2566 else if (strcasecmp(p, "NEVER") == 0) 2567 tx->evp.dsn_notify |= DSN_NEVER; 2568 } 2569 2570 if (tx->evp.dsn_notify & DSN_NEVER && 2571 tx->evp.dsn_notify & (DSN_SUCCESS | DSN_FAILURE | 2572 DSN_DELAY)) { 2573 smtp_reply(tx->session, 2574 "553 NOTIFY option NEVER cannot be" 2575 " combined with other options"); 2576 return; 2577 } 2578 } else if (ADVERTISE_EXT_DSN(tx->session) && strncasecmp(opt, "ORCPT=", 6) == 0) { 2579 opt += 6; 2580 2581 if (strncasecmp(opt, "rfc822;", 7) == 0) 2582 opt += 7; 2583 2584 if (!text_to_mailaddr(&tx->evp.dsn_orcpt, opt) || 2585 !valid_localpart(tx->evp.dsn_orcpt.user) || 2586 (strlen(tx->evp.dsn_orcpt.domain) != 0 && 2587 !valid_domainpart(tx->evp.dsn_orcpt.domain))) { 2588 smtp_reply(tx->session, 2589 "553 ORCPT address syntax error"); 2590 return; 2591 } 2592 } else { 2593 smtp_reply(tx->session, "503 Unsupported option %s", opt); 2594 return; 2595 } 2596 } 2597 2598 m_create(p_lka, IMSG_SMTP_EXPAND_RCPT, 0, 0, -1); 2599 m_add_id(p_lka, tx->session->id); 2600 m_add_envelope(p_lka, &tx->evp); 2601 m_close(p_lka); 2602 tree_xset(&wait_lka_rcpt, tx->session->id, tx->session); 2603 } 2604 2605 static void 2606 smtp_tx_open_message(struct smtp_tx *tx) 2607 { 2608 m_create(p_queue, IMSG_SMTP_MESSAGE_OPEN, 0, 0, -1); 2609 m_add_id(p_queue, tx->session->id); 2610 m_add_msgid(p_queue, tx->msgid); 2611 m_close(p_queue); 2612 tree_xset(&wait_queue_fd, tx->session->id, tx->session); 2613 } 2614 2615 static void 2616 smtp_tx_commit(struct smtp_tx *tx) 2617 { 2618 m_create(p_queue, IMSG_SMTP_MESSAGE_COMMIT, 0, 0, -1); 2619 m_add_id(p_queue, tx->session->id); 2620 m_add_msgid(p_queue, tx->msgid); 2621 m_close(p_queue); 2622 tree_xset(&wait_queue_commit, tx->session->id, tx->session); 2623 smtp_filter_data_end(tx->session); 2624 } 2625 2626 static void 2627 smtp_tx_rollback(struct smtp_tx *tx) 2628 { 2629 m_create(p_queue, IMSG_SMTP_MESSAGE_ROLLBACK, 0, 0, -1); 2630 m_add_msgid(p_queue, tx->msgid); 2631 m_close(p_queue); 2632 smtp_report_tx_rollback(tx->session, tx->msgid); 2633 smtp_report_tx_reset(tx->session, tx->msgid); 2634 smtp_filter_data_end(tx->session); 2635 } 2636 2637 static int 2638 smtp_tx_dataline(struct smtp_tx *tx, const char *line) 2639 { 2640 struct rfc5322_result res; 2641 int r; 2642 2643 log_trace(TRACE_SMTP, "<<< [MSG] %s", line); 2644 2645 if (!strcmp(line, ".")) { 2646 smtp_report_protocol_client(tx->session, "."); 2647 log_trace(TRACE_SMTP, "<<< [EOM]"); 2648 if (tx->error) 2649 return 1; 2650 line = NULL; 2651 } 2652 else { 2653 /* ignore data line if an error is set */ 2654 if (tx->error) 2655 return 0; 2656 2657 /* escape lines starting with a '.' */ 2658 if (line[0] == '.') 2659 line += 1; 2660 } 2661 2662 if (rfc5322_push(tx->parser, line) == -1) { 2663 log_warnx("failed to push dataline"); 2664 tx->error = TX_ERROR_INTERNAL; 2665 return 0; 2666 } 2667 2668 for(;;) { 2669 r = rfc5322_next(tx->parser, &res); 2670 switch (r) { 2671 case -1: 2672 if (errno == ENOMEM) 2673 tx->error = TX_ERROR_INTERNAL; 2674 else 2675 tx->error = TX_ERROR_MALFORMED; 2676 return 0; 2677 2678 case RFC5322_NONE: 2679 /* Need more data */ 2680 return 0; 2681 2682 case RFC5322_HEADER_START: 2683 /* ignore bcc */ 2684 if (!strcasecmp("Bcc", res.hdr)) 2685 continue; 2686 2687 if (!strcasecmp("To", res.hdr) || 2688 !strcasecmp("Cc", res.hdr) || 2689 !strcasecmp("From", res.hdr)) { 2690 rfc5322_unfold_header(tx->parser); 2691 continue; 2692 } 2693 2694 if (!strcasecmp("Received", res.hdr)) { 2695 if (++tx->rcvcount >= MAX_HOPS_COUNT) { 2696 log_warnx("warn: loop detected"); 2697 tx->error = TX_ERROR_LOOP; 2698 return 0; 2699 } 2700 } 2701 else if (!tx->has_date && !strcasecmp("Date", res.hdr)) 2702 tx->has_date = 1; 2703 else if (!tx->has_message_id && 2704 !strcasecmp("Message-Id", res.hdr)) 2705 tx->has_message_id = 1; 2706 2707 smtp_message_printf(tx, "%s:%s\n", res.hdr, res.value); 2708 break; 2709 2710 case RFC5322_HEADER_CONT: 2711 2712 if (!strcasecmp("Bcc", res.hdr) || 2713 !strcasecmp("To", res.hdr) || 2714 !strcasecmp("Cc", res.hdr) || 2715 !strcasecmp("From", res.hdr)) 2716 continue; 2717 2718 smtp_message_printf(tx, "%s\n", res.value); 2719 break; 2720 2721 case RFC5322_HEADER_END: 2722 if (!strcasecmp("To", res.hdr) || 2723 !strcasecmp("Cc", res.hdr) || 2724 !strcasecmp("From", res.hdr)) 2725 header_domain_append_callback(tx, res.hdr, 2726 res.value); 2727 break; 2728 2729 case RFC5322_END_OF_HEADERS: 2730 if (tx->session->listener->local || 2731 tx->session->listener->port == 587) { 2732 2733 if (!tx->has_date) { 2734 log_debug("debug: %p: adding Date", tx); 2735 smtp_message_printf(tx, "Date: %s\n", 2736 time_to_text(tx->time)); 2737 } 2738 2739 if (!tx->has_message_id) { 2740 log_debug("debug: %p: adding Message-ID", tx); 2741 smtp_message_printf(tx, 2742 "Message-ID: <%016"PRIx64"@%s>\n", 2743 generate_uid(), 2744 tx->session->listener->hostname); 2745 } 2746 } 2747 break; 2748 2749 case RFC5322_BODY_START: 2750 case RFC5322_BODY: 2751 smtp_message_printf(tx, "%s\n", res.value); 2752 break; 2753 2754 case RFC5322_END_OF_MESSAGE: 2755 return 1; 2756 2757 default: 2758 fatalx("%s", __func__); 2759 } 2760 } 2761 } 2762 2763 static int 2764 smtp_tx_filtered_dataline(struct smtp_tx *tx, const char *line) 2765 { 2766 if (!strcmp(line, ".")) 2767 line = NULL; 2768 else { 2769 /* ignore data line if an error is set */ 2770 if (tx->error) 2771 return 0; 2772 } 2773 io_printf(tx->filter, "%s\n", line ? line : "."); 2774 return line ? 0 : 1; 2775 } 2776 2777 static void 2778 smtp_tx_eom(struct smtp_tx *tx) 2779 { 2780 smtp_filter_phase(FILTER_COMMIT, tx->session, NULL); 2781 } 2782 2783 static int 2784 smtp_message_fd(struct smtp_tx *tx, int fd) 2785 { 2786 struct smtp_session *s; 2787 2788 s = tx->session; 2789 2790 log_debug("smtp: %p: message fd %d", s, fd); 2791 2792 if ((tx->ofile = fdopen(fd, "w")) == NULL) { 2793 close(fd); 2794 smtp_reply(s, "421 %s Temporary Error", 2795 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 2796 smtp_enter_state(s, STATE_QUIT); 2797 return 0; 2798 } 2799 return 1; 2800 } 2801 2802 static void 2803 filter_session_io(struct io *io, int evt, void *arg) 2804 { 2805 struct smtp_tx*tx = arg; 2806 char*line = NULL; 2807 ssize_t len; 2808 2809 log_trace(TRACE_IO, "filter session io (smtp): %p: %s %s", tx, io_strevent(evt), 2810 io_strio(io)); 2811 2812 switch (evt) { 2813 case IO_DATAIN: 2814 nextline: 2815 line = io_getline(tx->filter, &len); 2816 /* No complete line received */ 2817 if (line == NULL) 2818 return; 2819 2820 if (smtp_tx_dataline(tx, line)) { 2821 smtp_tx_eom(tx); 2822 return; 2823 } 2824 2825 goto nextline; 2826 } 2827 } 2828 2829 static void 2830 smtp_filter_fd(struct smtp_tx *tx, int fd) 2831 { 2832 struct smtp_session *s; 2833 2834 s = tx->session; 2835 2836 log_debug("smtp: %p: filter fd %d", s, fd); 2837 2838 tx->filter = io_new(); 2839 io_set_fd(tx->filter, fd); 2840 io_set_callback(tx->filter, filter_session_io, tx); 2841 } 2842 2843 static void 2844 smtp_message_begin(struct smtp_tx *tx) 2845 { 2846 struct smtp_session *s; 2847 X509 *x; 2848 int (*m_printf)(struct smtp_tx *, const char *, ...); 2849 2850 m_printf = smtp_message_printf; 2851 if (tx->filter) 2852 m_printf = smtp_filter_printf; 2853 2854 s = tx->session; 2855 2856 log_debug("smtp: %p: message begin", s); 2857 2858 smtp_reply(s, "354 Enter mail, end with \".\"" 2859 " on a line by itself"); 2860 2861 if (s->junk || (s->tx && s->tx->junk)) 2862 m_printf(tx, "X-Spam: Yes\n"); 2863 2864 m_printf(tx, "Received: "); 2865 if (!(s->listener->flags & F_MASK_SOURCE)) { 2866 m_printf(tx, "from %s (%s %s%s%s)", 2867 s->helo, 2868 s->rdns, 2869 s->ss.ss_family == AF_INET6 ? "" : "[", 2870 ss_to_text(&s->ss), 2871 s->ss.ss_family == AF_INET6 ? "" : "]"); 2872 } 2873 m_printf(tx, "\n\tby %s (%s) with %sSMTP%s%s id %08x", 2874 s->smtpname, 2875 SMTPD_NAME, 2876 s->flags & SF_EHLO ? "E" : "", 2877 s->flags & SF_SECURE ? "S" : "", 2878 s->flags & SF_AUTHENTICATED ? "A" : "", 2879 tx->msgid); 2880 2881 if (s->flags & SF_SECURE) { 2882 x = SSL_get_peer_certificate(io_tls(s->io)); 2883 m_printf(tx, " (%s:%s:%d:%s)", 2884 SSL_get_version(io_tls(s->io)), 2885 SSL_get_cipher_name(io_tls(s->io)), 2886 SSL_get_cipher_bits(io_tls(s->io), NULL), 2887 (s->flags & SF_VERIFIED) ? "YES" : (x ? "FAIL" : "NO")); 2888 X509_free(x); 2889 2890 if (s->listener->flags & F_RECEIVEDAUTH) { 2891 m_printf(tx, " auth=%s", 2892 s->username[0] ? "yes" : "no"); 2893 if (s->username[0]) 2894 m_printf(tx, " user=%s", s->username); 2895 } 2896 } 2897 2898 if (tx->rcptcount == 1) { 2899 m_printf(tx, "\n\tfor <%s@%s>", 2900 tx->evp.rcpt.user, 2901 tx->evp.rcpt.domain); 2902 } 2903 2904 m_printf(tx, ";\n\t%s\n", time_to_text(time(&tx->time))); 2905 2906 smtp_enter_state(s, STATE_BODY); 2907 } 2908 2909 static void 2910 smtp_message_end(struct smtp_tx *tx) 2911 { 2912 struct smtp_session *s; 2913 2914 s = tx->session; 2915 2916 log_debug("debug: %p: end of message, error=%d", s, tx->error); 2917 2918 fclose(tx->ofile); 2919 tx->ofile = NULL; 2920 2921 switch(tx->error) { 2922 case TX_OK: 2923 smtp_tx_commit(tx); 2924 return; 2925 2926 case TX_ERROR_SIZE: 2927 smtp_reply(s, "554 %s %s: Transaction failed, message too big", 2928 esc_code(ESC_STATUS_PERMFAIL, ESC_MESSAGE_TOO_BIG_FOR_SYSTEM), 2929 esc_description(ESC_MESSAGE_TOO_BIG_FOR_SYSTEM)); 2930 break; 2931 2932 case TX_ERROR_LOOP: 2933 smtp_reply(s, "500 %s %s: Loop detected", 2934 esc_code(ESC_STATUS_PERMFAIL, ESC_ROUTING_LOOP_DETECTED), 2935 esc_description(ESC_ROUTING_LOOP_DETECTED)); 2936 break; 2937 2938 case TX_ERROR_MALFORMED: 2939 smtp_reply(s, "550 %s %s: Message is not RFC 2822 compliant", 2940 esc_code(ESC_STATUS_PERMFAIL, ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED), 2941 esc_description(ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED)); 2942 break; 2943 2944 case TX_ERROR_IO: 2945 case TX_ERROR_RESOURCES: 2946 smtp_reply(s, "421 %s Temporary Error", 2947 esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); 2948 break; 2949 2950 default: 2951 /* fatal? */ 2952 smtp_reply(s, "421 Internal server error"); 2953 } 2954 2955 smtp_tx_rollback(tx); 2956 smtp_tx_free(tx); 2957 smtp_enter_state(s, STATE_HELO); 2958 } 2959 2960 static int 2961 smtp_filter_printf(struct smtp_tx *tx, const char *fmt, ...) 2962 { 2963 va_list ap; 2964 int len; 2965 2966 if (tx->error) 2967 return -1; 2968 2969 va_start(ap, fmt); 2970 len = io_vprintf(tx->filter, fmt, ap); 2971 va_end(ap); 2972 2973 if (len < 0) { 2974 log_warn("smtp-in: session %016"PRIx64": vfprintf", tx->session->id); 2975 tx->error = TX_ERROR_IO; 2976 } 2977 else 2978 tx->odatalen += len; 2979 2980 return len; 2981 } 2982 2983 static int 2984 smtp_message_printf(struct smtp_tx *tx, const char *fmt, ...) 2985 { 2986 va_list ap; 2987 int len; 2988 2989 if (tx->error) 2990 return -1; 2991 2992 va_start(ap, fmt); 2993 len = vfprintf(tx->ofile, fmt, ap); 2994 va_end(ap); 2995 2996 if (len == -1) { 2997 log_warn("smtp-in: session %016"PRIx64": vfprintf", tx->session->id); 2998 tx->error = TX_ERROR_IO; 2999 } 3000 else 3001 tx->odatalen += len; 3002 3003 return len; 3004 } 3005 3006 #define CASE(x) case x : return #x 3007 3008 const char * 3009 smtp_strstate(int state) 3010 { 3011 static char buf[32]; 3012 3013 switch (state) { 3014 CASE(STATE_NEW); 3015 CASE(STATE_CONNECTED); 3016 CASE(STATE_TLS); 3017 CASE(STATE_HELO); 3018 CASE(STATE_AUTH_INIT); 3019 CASE(STATE_AUTH_USERNAME); 3020 CASE(STATE_AUTH_PASSWORD); 3021 CASE(STATE_AUTH_FINALIZE); 3022 CASE(STATE_BODY); 3023 CASE(STATE_QUIT); 3024 default: 3025 (void)snprintf(buf, sizeof(buf), "STATE_??? (%d)", state); 3026 return (buf); 3027 } 3028 } 3029 3030 3031 static void 3032 smtp_report_link_connect(struct smtp_session *s, const char *rdns, int fcrdns, 3033 const struct sockaddr_storage *ss_src, 3034 const struct sockaddr_storage *ss_dest) 3035 { 3036 if (! SESSION_FILTERED(s)) 3037 return; 3038 3039 report_smtp_link_connect("smtp-in", s->id, rdns, fcrdns, ss_src, ss_dest); 3040 } 3041 3042 static void 3043 smtp_report_link_greeting(struct smtp_session *s, 3044 const char *domain) 3045 { 3046 if (! SESSION_FILTERED(s)) 3047 return; 3048 3049 report_smtp_link_greeting("smtp-in", s->id, domain); 3050 } 3051 3052 static void 3053 smtp_report_link_identify(struct smtp_session *s, const char *method, const char *identity) 3054 { 3055 if (! SESSION_FILTERED(s)) 3056 return; 3057 3058 report_smtp_link_identify("smtp-in", s->id, method, identity); 3059 } 3060 3061 static void 3062 smtp_report_link_tls(struct smtp_session *s, const char *ssl) 3063 { 3064 if (! SESSION_FILTERED(s)) 3065 return; 3066 3067 report_smtp_link_tls("smtp-in", s->id, ssl); 3068 } 3069 3070 static void 3071 smtp_report_link_disconnect(struct smtp_session *s) 3072 { 3073 if (! SESSION_FILTERED(s)) 3074 return; 3075 3076 report_smtp_link_disconnect("smtp-in", s->id); 3077 } 3078 3079 static void 3080 smtp_report_link_auth(struct smtp_session *s, const char *user, const char *result) 3081 { 3082 if (! SESSION_FILTERED(s)) 3083 return; 3084 3085 report_smtp_link_auth("smtp-in", s->id, user, result); 3086 } 3087 3088 static void 3089 smtp_report_tx_reset(struct smtp_session *s, uint32_t msgid) 3090 { 3091 if (! SESSION_FILTERED(s)) 3092 return; 3093 3094 report_smtp_tx_reset("smtp-in", s->id, msgid); 3095 } 3096 3097 static void 3098 smtp_report_tx_begin(struct smtp_session *s, uint32_t msgid) 3099 { 3100 if (! SESSION_FILTERED(s)) 3101 return; 3102 3103 report_smtp_tx_begin("smtp-in", s->id, msgid); 3104 } 3105 3106 static void 3107 smtp_report_tx_mail(struct smtp_session *s, uint32_t msgid, const char *address, int ok) 3108 { 3109 char mailaddr[SMTPD_MAXMAILADDRSIZE]; 3110 char *p; 3111 3112 if (! SESSION_FILTERED(s)) 3113 return; 3114 3115 if ((p = strchr(address, '<')) == NULL) 3116 return; 3117 (void)strlcpy(mailaddr, p + 1, sizeof mailaddr); 3118 if ((p = strchr(mailaddr, '>')) == NULL) 3119 return; 3120 *p = '\0'; 3121 3122 report_smtp_tx_mail("smtp-in", s->id, msgid, mailaddr, ok); 3123 } 3124 3125 static void 3126 smtp_report_tx_rcpt(struct smtp_session *s, uint32_t msgid, const char *address, int ok) 3127 { 3128 char mailaddr[SMTPD_MAXMAILADDRSIZE]; 3129 char *p; 3130 3131 if (! SESSION_FILTERED(s)) 3132 return; 3133 3134 if ((p = strchr(address, '<')) == NULL) 3135 return; 3136 (void)strlcpy(mailaddr, p + 1, sizeof mailaddr); 3137 if ((p = strchr(mailaddr, '>')) == NULL) 3138 return; 3139 *p = '\0'; 3140 3141 report_smtp_tx_rcpt("smtp-in", s->id, msgid, mailaddr, ok); 3142 } 3143 3144 static void 3145 smtp_report_tx_envelope(struct smtp_session *s, uint32_t msgid, uint64_t evpid) 3146 { 3147 if (! SESSION_FILTERED(s)) 3148 return; 3149 3150 report_smtp_tx_envelope("smtp-in", s->id, msgid, evpid); 3151 } 3152 3153 static void 3154 smtp_report_tx_data(struct smtp_session *s, uint32_t msgid, int ok) 3155 { 3156 if (! SESSION_FILTERED(s)) 3157 return; 3158 3159 report_smtp_tx_data("smtp-in", s->id, msgid, ok); 3160 } 3161 3162 static void 3163 smtp_report_tx_commit(struct smtp_session *s, uint32_t msgid, size_t msgsz) 3164 { 3165 if (! SESSION_FILTERED(s)) 3166 return; 3167 3168 report_smtp_tx_commit("smtp-in", s->id, msgid, msgsz); 3169 } 3170 3171 static void 3172 smtp_report_tx_rollback(struct smtp_session *s, uint32_t msgid) 3173 { 3174 if (! SESSION_FILTERED(s)) 3175 return; 3176 3177 report_smtp_tx_rollback("smtp-in", s->id, msgid); 3178 } 3179 3180 static void 3181 smtp_report_protocol_client(struct smtp_session *s, const char *command) 3182 { 3183 if (! SESSION_FILTERED(s)) 3184 return; 3185 3186 report_smtp_protocol_client("smtp-in", s->id, command); 3187 } 3188 3189 static void 3190 smtp_report_protocol_server(struct smtp_session *s, const char *response) 3191 { 3192 if (! SESSION_FILTERED(s)) 3193 return; 3194 3195 report_smtp_protocol_server("smtp-in", s->id, response); 3196 } 3197 3198 static void 3199 smtp_report_filter_response(struct smtp_session *s, int phase, int response, const char *param) 3200 { 3201 if (! SESSION_FILTERED(s)) 3202 return; 3203 3204 report_smtp_filter_response("smtp-in", s->id, phase, response, param); 3205 } 3206 3207 static void 3208 smtp_report_timeout(struct smtp_session *s) 3209 { 3210 if (! SESSION_FILTERED(s)) 3211 return; 3212 3213 report_smtp_timeout("smtp-in", s->id); 3214 } 3215