1 /* $OpenBSD: smtp_session.c,v 1.162 2012/05/08 11:52:57 eric Exp $ */ 2 3 /* 4 * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.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/param.h> 26 #include <sys/socket.h> 27 28 #include <netinet/in.h> 29 30 #include <ctype.h> 31 #include <event.h> 32 #include <imsg.h> 33 #include <resolv.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <unistd.h> 37 38 #include <openssl/ssl.h> 39 40 #include "smtpd.h" 41 #include "log.h" 42 43 void ssl_error(const char *); 44 45 static int session_rfc5321_helo_handler(struct session *, char *); 46 static int session_rfc5321_ehlo_handler(struct session *, char *); 47 static int session_rfc5321_rset_handler(struct session *, char *); 48 static int session_rfc5321_noop_handler(struct session *, char *); 49 static int session_rfc5321_data_handler(struct session *, char *); 50 static int session_rfc5321_mail_handler(struct session *, char *); 51 static int session_rfc5321_rcpt_handler(struct session *, char *); 52 static int session_rfc5321_vrfy_handler(struct session *, char *); 53 static int session_rfc5321_expn_handler(struct session *, char *); 54 static int session_rfc5321_turn_handler(struct session *, char *); 55 static int session_rfc5321_help_handler(struct session *, char *); 56 static int session_rfc5321_quit_handler(struct session *, char *); 57 58 static int session_rfc1652_mail_handler(struct session *, char *); 59 60 static int session_rfc3207_stls_handler(struct session *, char *); 61 62 static int session_rfc4954_auth_handler(struct session *, char *); 63 static void session_rfc4954_auth_plain(struct session *, char *); 64 static void session_rfc4954_auth_login(struct session *, char *); 65 66 static void session_line(struct session *, char *, size_t); 67 static void session_read_data(struct session *, char *); 68 static void session_command(struct session *, char *); 69 static void session_respond_delayed(int, short, void *); 70 static int session_set_mailaddr(struct mailaddr *, char *); 71 static void session_imsg(struct session *, enum smtp_proc_type, 72 enum imsg_type, u_int32_t, pid_t, int, void *, u_int16_t); 73 74 static void session_enter_state(struct session *, int); 75 76 const char *session_strstate(int); 77 78 struct session_cmd { 79 char *name; 80 int (*func)(struct session *, char *); 81 }; 82 83 struct session_cmd rfc5321_cmdtab[] = { 84 { "helo", session_rfc5321_helo_handler }, 85 { "ehlo", session_rfc5321_ehlo_handler }, 86 { "rset", session_rfc5321_rset_handler }, 87 { "noop", session_rfc5321_noop_handler }, 88 { "data", session_rfc5321_data_handler }, 89 { "mail from", session_rfc5321_mail_handler }, 90 { "rcpt to", session_rfc5321_rcpt_handler }, 91 { "vrfy", session_rfc5321_vrfy_handler }, 92 { "expn", session_rfc5321_expn_handler }, 93 { "turn", session_rfc5321_turn_handler }, 94 { "help", session_rfc5321_help_handler }, 95 { "quit", session_rfc5321_quit_handler } 96 }; 97 98 struct session_cmd rfc1652_cmdtab[] = { 99 { "mail from", session_rfc1652_mail_handler }, 100 }; 101 102 struct session_cmd rfc3207_cmdtab[] = { 103 { "starttls", session_rfc3207_stls_handler } 104 }; 105 106 struct session_cmd rfc4954_cmdtab[] = { 107 { "auth", session_rfc4954_auth_handler } 108 }; 109 110 static int 111 session_rfc3207_stls_handler(struct session *s, char *args) 112 { 113 if (! ADVERTISE_TLS(s)) 114 return 0; 115 116 if (s->s_state == S_GREETED) { 117 session_respond(s, "503 Polite people say HELO first"); 118 return 1; 119 } 120 121 if (s->s_state != S_HELO) { 122 session_respond(s, "503 TLS not allowed at this stage"); 123 return 1; 124 } 125 126 if (args != NULL) { 127 session_respond(s, "501 No parameters allowed"); 128 return 1; 129 } 130 131 session_enter_state(s, S_TLS); 132 session_respond(s, "220 Ready to start TLS"); 133 134 return 1; 135 } 136 137 static int 138 session_rfc4954_auth_handler(struct session *s, char *args) 139 { 140 char *method; 141 char *eom; 142 143 if (! ADVERTISE_AUTH(s)) { 144 if (s->s_flags & F_AUTHENTICATED) { 145 session_respond(s, "503 Already authenticated"); 146 return 1; 147 } else 148 return 0; 149 } 150 151 if (s->s_state == S_GREETED) { 152 session_respond(s, "503 Polite people say HELO first"); 153 return 1; 154 } 155 156 if (s->s_state != S_HELO) { 157 session_respond(s, "503 Session already in progress"); 158 return 1; 159 } 160 161 if (args == NULL) { 162 session_respond(s, "501 No parameters given"); 163 return 1; 164 } 165 166 method = args; 167 eom = strchr(args, ' '); 168 if (eom == NULL) 169 eom = strchr(args, '\t'); 170 if (eom != NULL) 171 *eom++ = '\0'; 172 173 if (strcasecmp(method, "PLAIN") == 0) 174 session_rfc4954_auth_plain(s, eom); 175 else if (strcasecmp(method, "LOGIN") == 0) 176 session_rfc4954_auth_login(s, eom); 177 else 178 session_respond(s, "504 AUTH method '%s' unsupported", method); 179 180 return 1; 181 } 182 183 static void 184 session_rfc4954_auth_plain(struct session *s, char *arg) 185 { 186 struct auth *a = &s->s_auth; 187 char buf[1024], *user, *pass; 188 int len; 189 190 switch (s->s_state) { 191 case S_HELO: 192 if (arg == NULL) { 193 session_enter_state(s, S_AUTH_INIT); 194 session_respond(s, "334 "); 195 return; 196 } 197 session_enter_state(s, S_AUTH_INIT); 198 /* FALLTHROUGH */ 199 200 case S_AUTH_INIT: 201 /* String is not NUL terminated, leave room. */ 202 if ((len = __b64_pton(arg, (unsigned char *)buf, sizeof(buf) - 1)) == -1) 203 goto abort; 204 /* buf is a byte string, NUL terminate. */ 205 buf[len] = '\0'; 206 207 /* 208 * Skip "foo" in "foo\0user\0pass", if present. 209 */ 210 user = memchr(buf, '\0', len); 211 if (user == NULL || user >= buf + len - 2) 212 goto abort; 213 user++; /* skip NUL */ 214 if (strlcpy(a->user, user, sizeof(a->user)) >= sizeof(a->user)) 215 goto abort; 216 217 pass = memchr(user, '\0', len - (user - buf)); 218 if (pass == NULL || pass >= buf + len - 2) 219 goto abort; 220 pass++; /* skip NUL */ 221 if (strlcpy(a->pass, pass, sizeof(a->pass)) >= sizeof(a->pass)) 222 goto abort; 223 224 session_enter_state(s, S_AUTH_FINALIZE); 225 226 a->id = s->s_id; 227 session_imsg(s, PROC_PARENT, IMSG_PARENT_AUTHENTICATE, 0, 0, -1, 228 a, sizeof(*a)); 229 230 bzero(a->pass, sizeof(a->pass)); 231 return; 232 233 default: 234 fatal("session_rfc4954_auth_plain: unknown state"); 235 } 236 237 abort: 238 session_respond(s, "501 Syntax error"); 239 session_enter_state(s, S_HELO); 240 } 241 242 static void 243 session_rfc4954_auth_login(struct session *s, char *arg) 244 { 245 struct auth *a = &s->s_auth; 246 247 switch (s->s_state) { 248 case S_HELO: 249 session_enter_state(s, S_AUTH_USERNAME); 250 session_respond(s, "334 VXNlcm5hbWU6"); 251 return; 252 253 case S_AUTH_USERNAME: 254 bzero(a->user, sizeof(a->user)); 255 if (__b64_pton(arg, (unsigned char *)a->user, sizeof(a->user) - 1) == -1) 256 goto abort; 257 258 session_enter_state(s, S_AUTH_PASSWORD); 259 session_respond(s, "334 UGFzc3dvcmQ6"); 260 return; 261 262 case S_AUTH_PASSWORD: 263 bzero(a->pass, sizeof(a->pass)); 264 if (__b64_pton(arg, (unsigned char *)a->pass, sizeof(a->pass) - 1) == -1) 265 goto abort; 266 267 session_enter_state(s, S_AUTH_FINALIZE); 268 269 a->id = s->s_id; 270 session_imsg(s, PROC_PARENT, IMSG_PARENT_AUTHENTICATE, 0, 0, -1, 271 a, sizeof(*a)); 272 273 bzero(a->pass, sizeof(a->pass)); 274 return; 275 276 default: 277 fatal("session_rfc4954_auth_login: unknown state"); 278 } 279 280 abort: 281 session_respond(s, "501 Syntax error"); 282 session_enter_state(s, S_HELO); 283 } 284 285 static int 286 session_rfc1652_mail_handler(struct session *s, char *args) 287 { 288 char *body; 289 290 if (s->s_state == S_GREETED) { 291 session_respond(s, "503 5.5.1 Polite people say HELO first"); 292 return 1; 293 } 294 295 for (body = strrchr(args, ' '); body != NULL; 296 body = strrchr(args, ' ')) { 297 *body++ = '\0'; 298 299 if (strncasecmp(body, "AUTH=", 5) == 0) { 300 log_debug("smtp: AUTH in MAIL FROM command, skipping"); 301 continue; 302 } 303 304 if (strncasecmp(body, "BODY=", 5) == 0) { 305 log_debug("smtp: BODY in MAIL FROM command"); 306 307 if (strncasecmp("body=7bit", body, 9) == 0) { 308 s->s_flags &= ~F_8BITMIME; 309 continue; 310 } 311 312 else if (strncasecmp("body=8bitmime", body, 13) != 0) { 313 session_respond(s, "503 5.5.4 Unsupported option %s", body); 314 return 1; 315 } 316 } 317 } 318 319 return session_rfc5321_mail_handler(s, args); 320 } 321 322 static int 323 session_rfc5321_helo_handler(struct session *s, char *args) 324 { 325 if (args == NULL) { 326 session_respond(s, "501 HELO requires domain address"); 327 return 1; 328 } 329 330 if (strlcpy(s->s_msg.helo, args, sizeof(s->s_msg.helo)) 331 >= sizeof(s->s_msg.helo)) { 332 session_respond(s, "501 Invalid domain name"); 333 return 1; 334 } 335 336 s->s_msg.session_id = s->s_id; 337 s->s_flags &= F_SECURE|F_AUTHENTICATED; 338 session_enter_state(s, S_HELO); 339 340 session_imsg(s, PROC_MFA, IMSG_MFA_HELO, 0, 0, -1, &s->s_msg, 341 sizeof(s->s_msg)); 342 return 1; 343 } 344 345 static int 346 session_rfc5321_ehlo_handler(struct session *s, char *args) 347 { 348 if (args == NULL) { 349 session_respond(s, "501 EHLO requires domain address"); 350 return 1; 351 } 352 353 if (strlcpy(s->s_msg.helo, args, sizeof(s->s_msg.helo)) 354 >= sizeof(s->s_msg.helo)) { 355 session_respond(s, "501 Invalid domain name"); 356 return 1; 357 } 358 359 s->s_msg.session_id = s->s_id; 360 s->s_flags &= F_SECURE|F_AUTHENTICATED; 361 s->s_flags |= F_EHLO; 362 s->s_flags |= F_8BITMIME; 363 session_enter_state(s, S_HELO); 364 365 session_imsg(s, PROC_MFA, IMSG_MFA_HELO, 0, 0, -1, &s->s_msg, 366 sizeof(s->s_msg)); 367 return 1; 368 } 369 370 static int 371 session_rfc5321_rset_handler(struct session *s, char *args) 372 { 373 session_enter_state(s, S_RSET); 374 375 session_imsg(s, PROC_MFA, IMSG_MFA_RSET, 0, 0, -1, &s->s_msg, 376 sizeof(s->s_msg)); 377 return 1; 378 } 379 380 static int 381 session_rfc5321_noop_handler(struct session *s, char *args) 382 { 383 session_respond(s, "250 2.0.0 OK"); 384 385 return 1; 386 } 387 388 static int 389 session_rfc5321_mail_handler(struct session *s, char *args) 390 { 391 if (s->s_state == S_GREETED) { 392 session_respond(s, "503 5.5.1 Polite people say HELO first"); 393 return 1; 394 } 395 396 if (s->s_state != S_HELO) { 397 session_respond(s, "503 5.5.1 Sender already specified"); 398 return 1; 399 } 400 401 if (! session_set_mailaddr(&s->s_msg.sender, args)) { 402 /* No need to even transmit to MFA, path is invalid */ 403 session_respond(s, "553 5.1.7 Sender address syntax error"); 404 return 1; 405 } 406 407 s->rcptcount = 0; 408 s->s_msg.id = 0; 409 410 session_enter_state(s, S_MAIL_MFA); 411 session_imsg(s, PROC_MFA, IMSG_MFA_MAIL, 0, 0, -1, &s->s_msg, 412 sizeof(s->s_msg)); 413 return 1; 414 } 415 416 static int 417 session_rfc5321_rcpt_handler(struct session *s, char *args) 418 { 419 if (s->s_state == S_GREETED) { 420 session_respond(s, "503 5.5.1 Polite people say HELO first"); 421 return 1; 422 } 423 424 if (s->s_state == S_HELO) { 425 session_respond(s, "503 5.5.1 Need MAIL before RCPT"); 426 return 1; 427 } 428 429 if (! session_set_mailaddr(&s->s_msg.rcpt, args)) { 430 /* No need to even transmit to MFA, path is invalid */ 431 session_respond(s, "553 5.1.3 Recipient address syntax error"); 432 return 1; 433 } 434 435 session_enter_state(s, S_RCPT_MFA); 436 session_imsg(s, PROC_MFA, IMSG_MFA_RCPT, 0, 0, -1, &s->s_msg, 437 sizeof(s->s_msg)); 438 return 1; 439 } 440 441 static int 442 session_rfc5321_quit_handler(struct session *s, char *args) 443 { 444 session_enter_state(s, S_QUIT); 445 session_respond(s, "221 2.0.0 %s Closing connection", env->sc_hostname); 446 /* 447 session_imsg(s, PROC_MFA, IMSG_MFA_QUIT, 0, 0, -1, &s->s_msg, 448 sizeof(s->s_msg)); 449 */ 450 return 1; 451 } 452 453 static int 454 session_rfc5321_data_handler(struct session *s, char *args) 455 { 456 if (s->s_state == S_GREETED) { 457 session_respond(s, "503 5.5.1 Polite people say HELO first"); 458 return 1; 459 } 460 461 if (s->s_state == S_HELO) { 462 session_respond(s, "503 5.5.1 Need MAIL before DATA"); 463 return 1; 464 } 465 466 if (s->s_state == S_MAIL) { 467 session_respond(s, "503 5.5.1 Need RCPT before DATA"); 468 return 1; 469 } 470 471 session_enter_state(s, S_DATA_QUEUE); 472 473 session_imsg(s, PROC_QUEUE, IMSG_QUEUE_MESSAGE_FILE, 0, 0, -1, 474 &s->s_msg, sizeof(s->s_msg)); 475 476 return 1; 477 } 478 479 static int 480 session_rfc5321_vrfy_handler(struct session *s, char *args) 481 { 482 session_respond(s, "252 5.5.1 Cannot VRFY; try RCPT to attempt delivery"); 483 484 return 1; 485 } 486 487 static int 488 session_rfc5321_expn_handler(struct session *s, char *args) 489 { 490 session_respond(s, "502 5.5.2 Sorry, we do not allow this operation"); 491 492 return 1; 493 } 494 495 static int 496 session_rfc5321_turn_handler(struct session *s, char *args) 497 { 498 session_respond(s, "502 5.5.2 Sorry, we do not allow this operation"); 499 500 return 1; 501 } 502 503 static int 504 session_rfc5321_help_handler(struct session *s, char *args) 505 { 506 session_respond(s, "214- This is OpenSMTPD"); 507 session_respond(s, "214- To report bugs in the implementation, please " 508 "contact bugs@openbsd.org"); 509 session_respond(s, "214- with full details"); 510 session_respond(s, "214 End of HELP info"); 511 512 return 1; 513 } 514 515 static void 516 session_enter_state(struct session *s, int newstate) 517 { 518 log_trace(TRACE_SMTP, "smtp: %p: %s -> %s", s, 519 session_strstate(s->s_state), 520 session_strstate(newstate)); 521 522 s->s_state = newstate; 523 } 524 525 static void 526 session_command(struct session *s, char *cmd) 527 { 528 char *ep, *args; 529 unsigned int i; 530 531 /* 532 * unlike other commands, "mail from" and "rcpt to" contain a 533 * space in the command name. 534 */ 535 if (strncasecmp("mail from:", cmd, 10) == 0 || 536 strncasecmp("rcpt to:", cmd, 8) == 0) 537 ep = strchr(cmd, ':'); 538 else 539 ep = strchr(cmd, ' '); 540 541 if (ep != NULL) { 542 *ep = '\0'; 543 args = ++ep; 544 while (isspace((int)*args)) 545 args++; 546 } else 547 args = NULL; 548 549 if (!(s->s_flags & F_EHLO)) 550 goto rfc5321; 551 552 /* RFC 1652 - 8BITMIME */ 553 for (i = 0; i < nitems(rfc1652_cmdtab); ++i) 554 if (strcasecmp(rfc1652_cmdtab[i].name, cmd) == 0) 555 break; 556 if (i < nitems(rfc1652_cmdtab)) { 557 if (rfc1652_cmdtab[i].func(s, args)) 558 return; 559 } 560 561 /* RFC 3207 - STARTTLS */ 562 for (i = 0; i < nitems(rfc3207_cmdtab); ++i) 563 if (strcasecmp(rfc3207_cmdtab[i].name, cmd) == 0) 564 break; 565 if (i < nitems(rfc3207_cmdtab)) { 566 if (rfc3207_cmdtab[i].func(s, args)) 567 return; 568 } 569 570 /* RFC 4954 - AUTH */ 571 for (i = 0; i < nitems(rfc4954_cmdtab); ++i) 572 if (strcasecmp(rfc4954_cmdtab[i].name, cmd) == 0) 573 break; 574 if (i < nitems(rfc4954_cmdtab)) { 575 if (rfc4954_cmdtab[i].func(s, args)) 576 return; 577 } 578 579 rfc5321: 580 /* RFC 5321 - SMTP */ 581 for (i = 0; i < nitems(rfc5321_cmdtab); ++i) 582 if (strcasecmp(rfc5321_cmdtab[i].name, cmd) == 0) 583 break; 584 if (i < nitems(rfc5321_cmdtab)) { 585 if (rfc5321_cmdtab[i].func(s, args)) 586 return; 587 } 588 589 session_respond(s, "500 Command unrecognized"); 590 } 591 592 void 593 session_io(struct io *io, int evt) 594 { 595 struct session *s = io->arg; 596 char *line; 597 ssize_t len; 598 599 log_trace(TRACE_IO, "smtp: %p: %s %s", s, io_strevent(evt), io_strio(io)); 600 601 switch(evt) { 602 603 case IO_TLSREADY: 604 s->s_flags |= F_SECURE; 605 if (s->s_l->flags & F_SMTPS) 606 stat_increment(STATS_SMTP_SMTPS); 607 if (s->s_l->flags & F_STARTTLS) 608 stat_increment(STATS_SMTP_STARTTLS); 609 if (s->s_state == S_INIT) { 610 io_set_write(&s->s_io); 611 session_respond(s, SMTPD_BANNER, env->sc_hostname); 612 } 613 session_enter_state(s, S_GREETED); 614 break; 615 616 case IO_DATAIN: 617 nextline: 618 line = iobuf_getline(&s->s_iobuf, &len); 619 if ((line == NULL && iobuf_len(&s->s_iobuf) >= SMTP_LINE_MAX) || 620 (line && len >= SMTP_LINE_MAX)) { 621 session_respond(s, "500 5.0.0 Line too long"); 622 session_enter_state(s, S_QUIT); 623 io_set_write(io); 624 return; 625 } 626 627 if (line == NULL) { 628 iobuf_normalize(&s->s_iobuf); 629 return; 630 } 631 632 if (s->s_state == S_DATACONTENT && strcmp(line, ".")) { 633 /* more data to come */ 634 session_line(s, line, len); 635 goto nextline; 636 } 637 638 /* pipelining not supported */ 639 if (iobuf_len(&s->s_iobuf)) { 640 session_respond(s, "500 5.0.0 Pipelining not supported"); 641 session_enter_state(s, S_QUIT); 642 io_set_write(io); 643 return; 644 } 645 646 session_line(s, line, len); 647 iobuf_normalize(&s->s_iobuf); 648 io_set_write(io); 649 break; 650 651 case IO_LOWAT: 652 if (s->s_state == S_QUIT) { 653 session_destroy(s, "done"); 654 break; 655 } 656 657 io_set_read(io); 658 659 /* wait for the client to start tls */ 660 if (s->s_state == S_TLS) { 661 ssl_session_init(s); 662 io_start_tls(io, s->s_ssl); 663 } 664 break; 665 666 case IO_TIMEOUT: 667 session_destroy(s, "timeout"); 668 break; 669 670 case IO_DISCONNECTED: 671 session_destroy(s, "disconnected"); 672 break; 673 674 case IO_ERROR: 675 session_destroy(s, "error"); 676 break; 677 678 default: 679 fatal("session_io()"); 680 } 681 } 682 683 void 684 session_pickup(struct session *s, struct submit_status *ss) 685 { 686 s->s_flags &= ~F_WAITIMSG; 687 688 if ((ss != NULL && ss->code == 421) || 689 (s->s_dstatus & DS_TEMPFAILURE)) { 690 env->stats->smtp.tempfail++; 691 session_respond(s, "421 Service temporarily unavailable"); 692 session_enter_state(s, S_QUIT); 693 io_reload(&s->s_io); 694 return; 695 } 696 697 switch (s->s_state) { 698 699 case S_CONNECTED: 700 session_enter_state(s, S_INIT); 701 s->s_msg.session_id = s->s_id; 702 s->s_msg.ss = s->s_ss; 703 session_imsg(s, PROC_MFA, IMSG_MFA_CONNECT, 0, 0, -1, 704 &s->s_msg, sizeof(s->s_msg)); 705 break; 706 707 case S_INIT: 708 if (ss->code != 250) { 709 session_destroy(s, "rejected by filter"); 710 return; 711 } 712 713 if (s->s_l->flags & F_SMTPS) { 714 ssl_session_init(s); 715 io_set_read(&s->s_io); 716 io_start_tls(&s->s_io, s->s_ssl); 717 return; 718 } 719 720 session_respond(s, SMTPD_BANNER, env->sc_hostname); 721 session_enter_state(s, S_GREETED); 722 break; 723 724 case S_AUTH_FINALIZE: 725 if (s->s_flags & F_AUTHENTICATED) 726 session_respond(s, "235 Authentication succeeded"); 727 else 728 session_respond(s, "535 Authentication failed"); 729 session_enter_state(s, S_HELO); 730 break; 731 732 case S_RSET: 733 session_respond(s, "250 2.0.0 Reset state"); 734 session_enter_state(s, S_HELO); 735 break; 736 737 case S_HELO: 738 if (ss->code != 250) { 739 session_enter_state(s, S_GREETED); 740 session_respond(s, "%d Helo rejected", ss->code); 741 break; 742 } 743 744 session_respond(s, "250%c%s Hello %s [%s], pleased to meet you", 745 (s->s_flags & F_EHLO) ? '-' : ' ', 746 env->sc_hostname, s->s_msg.helo, ss_to_text(&s->s_ss)); 747 748 if (s->s_flags & F_EHLO) { 749 /* unconditionnal extensions go first */ 750 session_respond(s, "250-8BITMIME"); 751 session_respond(s, "250-ENHANCEDSTATUSCODES"); 752 753 /* XXX - we also want to support reading SIZE from MAIL parameters */ 754 session_respond(s, "250-SIZE %zu", env->sc_maxsize); 755 756 if (ADVERTISE_TLS(s)) 757 session_respond(s, "250-STARTTLS"); 758 759 if (ADVERTISE_AUTH(s)) 760 session_respond(s, "250-AUTH PLAIN LOGIN"); 761 session_respond(s, "250 HELP"); 762 } 763 break; 764 765 case S_MAIL_MFA: 766 if (ss->code != 250) { 767 session_enter_state(s, S_HELO); 768 session_respond(s, "%d Sender rejected", ss->code); 769 break; 770 } 771 772 session_enter_state(s, S_MAIL_QUEUE); 773 s->s_msg.sender = ss->u.maddr; 774 775 session_imsg(s, PROC_QUEUE, IMSG_QUEUE_CREATE_MESSAGE, 0, 0, -1, 776 &s->s_msg, sizeof(s->s_msg)); 777 break; 778 779 case S_MAIL_QUEUE: 780 session_enter_state(s, S_MAIL); 781 session_respond(s, "%d 2.1.0 Sender ok", ss->code); 782 break; 783 784 case S_RCPT_MFA: 785 /* recipient was not accepted */ 786 if (ss->code != 250) { 787 /* We do not have a valid recipient, downgrade state */ 788 if (s->rcptcount == 0) 789 session_enter_state(s, S_MAIL); 790 else 791 session_enter_state(s, S_RCPT); 792 session_respond(s, "%d 5.0.0 Recipient rejected: %s@%s", ss->code, 793 s->s_msg.rcpt.user, 794 s->s_msg.rcpt.domain); 795 break; 796 } 797 798 session_enter_state(s, S_RCPT); 799 s->rcptcount++; 800 s->s_msg.dest = ss->u.maddr; 801 session_respond(s, "%d 2.0.0 Recipient ok", ss->code); 802 break; 803 804 case S_DATA_QUEUE: 805 session_enter_state(s, S_DATACONTENT); 806 session_respond(s, "354 Enter mail, end with \".\" on a line by" 807 " itself"); 808 809 fprintf(s->datafp, "Received: from %s (%s [%s])\n", 810 s->s_msg.helo, s->s_hostname, ss_to_text(&s->s_ss)); 811 fprintf(s->datafp, "\tby %s (OpenSMTPD) with %sSMTP id %08x", 812 env->sc_hostname, s->s_flags & F_EHLO ? "E" : "", 813 evpid_to_msgid(s->s_msg.id)); 814 815 if (s->s_flags & F_SECURE) { 816 fprintf(s->datafp, "\n\t(version=%s cipher=%s bits=%d)", 817 SSL_get_cipher_version(s->s_ssl), 818 SSL_get_cipher_name(s->s_ssl), 819 SSL_get_cipher_bits(s->s_ssl, NULL)); 820 } 821 if (s->rcptcount == 1) 822 fprintf(s->datafp, "\n\tfor <%s@%s>; ", 823 s->s_msg.rcpt.user, 824 s->s_msg.rcpt.domain); 825 else 826 fprintf(s->datafp, ";\n\t"); 827 828 fprintf(s->datafp, "%s\n", time_to_text(time(NULL))); 829 break; 830 831 case S_DATACONTENT: 832 if (ss->code != 250) 833 s->s_dstatus |= DS_PERMFAILURE; 834 session_read_data(s, ss->u.dataline); 835 break; 836 837 case S_DONE: 838 session_respond(s, "250 2.0.0 %08x Message accepted for delivery", 839 evpid_to_msgid(s->s_msg.id)); 840 log_info("%08x: from=<%s%s%s>, size=%ld, nrcpts=%zu, proto=%s, " 841 "relay=%s [%s]", 842 evpid_to_msgid(s->s_msg.id), 843 s->s_msg.sender.user, 844 s->s_msg.sender.user[0] == '\0' ? "" : "@", 845 s->s_msg.sender.domain, 846 s->s_datalen, 847 s->rcptcount, 848 s->s_flags & F_EHLO ? "ESMTP" : "SMTP", 849 s->s_hostname, 850 ss_to_text(&s->s_ss)); 851 852 session_enter_state(s, S_HELO); 853 s->s_msg.id = 0; 854 bzero(&s->s_nresp, sizeof(s->s_nresp)); 855 break; 856 857 default: 858 fatal("session_pickup: unknown state"); 859 } 860 861 io_reload(&s->s_io); 862 } 863 864 static void 865 session_line(struct session *s, char *line, size_t len) 866 { 867 struct submit_status ss; 868 869 if (s->s_state != S_DATACONTENT) 870 log_trace(TRACE_SMTP, "smtp: %p: <<< %s", s, line); 871 872 switch (s->s_state) { 873 case S_AUTH_INIT: 874 if (s->s_dstatus & DS_TEMPFAILURE) 875 goto tempfail; 876 session_rfc4954_auth_plain(s, line); 877 break; 878 879 case S_AUTH_USERNAME: 880 case S_AUTH_PASSWORD: 881 if (s->s_dstatus & DS_TEMPFAILURE) 882 goto tempfail; 883 session_rfc4954_auth_login(s, line); 884 break; 885 886 case S_GREETED: 887 case S_HELO: 888 case S_MAIL: 889 case S_RCPT: 890 if (s->s_dstatus & DS_TEMPFAILURE) 891 goto tempfail; 892 session_command(s, line); 893 break; 894 895 case S_DATACONTENT: 896 if (env->filtermask & FILTER_DATALINE) { 897 bzero(&ss, sizeof(ss)); 898 ss.id = s->s_id; 899 if (strlcpy(ss.u.dataline, line, 900 sizeof(ss.u.dataline)) >= sizeof(ss.u.dataline)) 901 fatal("session_line: data truncation"); 902 903 session_imsg(s, PROC_MFA, IMSG_MFA_DATALINE, 904 0, 0, -1, &ss, sizeof(ss)); 905 } else { 906 /* no filtering */ 907 session_read_data(s, line); 908 } 909 break; 910 911 default: 912 log_debug("session_read: %i", s->s_state); 913 fatalx("session_read: unexpected state"); 914 } 915 916 return; 917 918 tempfail: 919 session_respond(s, "421 4.0.0 Service temporarily unavailable"); 920 env->stats->smtp.tempfail++; 921 session_enter_state(s, S_QUIT); 922 } 923 924 static void 925 session_read_data(struct session *s, char *line) 926 { 927 size_t datalen; 928 size_t len; 929 size_t i; 930 931 if (strcmp(line, ".") == 0) { 932 s->s_datalen = ftell(s->datafp); 933 if (! safe_fclose(s->datafp)) 934 s->s_dstatus |= DS_TEMPFAILURE; 935 s->datafp = NULL; 936 937 if (s->s_dstatus & DS_PERMFAILURE) { 938 session_respond(s, "554 5.0.0 Transaction failed"); 939 session_enter_state(s, S_HELO); 940 } else if (s->s_dstatus & DS_TEMPFAILURE) { 941 session_respond(s, "421 4.0.0 Temporary failure"); 942 session_enter_state(s, S_QUIT); 943 env->stats->smtp.tempfail++; 944 } else { 945 session_imsg(s, PROC_QUEUE, IMSG_QUEUE_COMMIT_MESSAGE, 946 0, 0, -1, &s->s_msg, sizeof(s->s_msg)); 947 session_enter_state(s, S_DONE); 948 } 949 return; 950 } 951 952 /* Don't waste resources on message if it's going to bin anyway. */ 953 if (s->s_dstatus & (DS_PERMFAILURE|DS_TEMPFAILURE)) 954 return; 955 956 /* "If the first character is a period and there are other characters 957 * on the line, the first character is deleted." [4.5.2] 958 */ 959 if (*line == '.') 960 line++; 961 962 len = strlen(line); 963 964 /* If size of data overflows a size_t or exceeds max size allowed 965 * for a message, set permanent failure. 966 */ 967 datalen = ftell(s->datafp); 968 if (SIZE_MAX - datalen < len + 1 || 969 datalen + len + 1 > env->sc_maxsize) { 970 s->s_dstatus |= DS_PERMFAILURE; 971 return; 972 } 973 974 if (! (s->s_flags & F_8BITMIME)) { 975 for (i = 0; i < len; ++i) 976 if (line[i] & 0x80) 977 line[i] = line[i] & 0x7f; 978 } 979 980 if (fprintf(s->datafp, "%s\n", line) != (int)len + 1) 981 s->s_dstatus |= DS_TEMPFAILURE; 982 } 983 984 void 985 session_destroy(struct session *s, const char * reason) 986 { 987 size_t resume; 988 989 log_debug("smtp: %p: deleting session: %s", s, reason); 990 991 if (s->s_flags & F_ZOMBIE) 992 goto finalize; 993 994 if (s->datafp != NULL) 995 fclose(s->datafp); 996 997 if (s->s_msg.id != 0 && s->s_state != S_DONE) 998 imsg_compose_event(env->sc_ievs[PROC_QUEUE], 999 IMSG_QUEUE_REMOVE_MESSAGE, 0, 0, -1, &s->s_msg, 1000 sizeof(s->s_msg)); 1001 1002 if (s->s_ssl) { 1003 if (s->s_l->flags & F_SMTPS) 1004 if (s->s_flags & F_SECURE) 1005 stat_decrement(STATS_SMTP_SMTPS); 1006 if (s->s_l->flags & F_STARTTLS) 1007 if (s->s_flags & F_SECURE) 1008 stat_decrement(STATS_SMTP_STARTTLS); 1009 } 1010 1011 event_del(&s->s_ev); /* in case something was scheduled */ 1012 io_clear(&s->s_io); 1013 iobuf_clear(&s->s_iobuf); 1014 1015 /* resume when session count decreases to 95% */ 1016 resume = env->sc_maxconn * 95 / 100; 1017 if (stat_decrement(STATS_SMTP_SESSION) == resume) { 1018 log_warnx("re-enabling incoming connections"); 1019 smtp_resume(); 1020 } 1021 1022 /* If the session is waiting for an imsg, do not kill it now, since 1023 * the id must still be valid. 1024 */ 1025 if (s->s_flags & F_WAITIMSG) { 1026 s->s_flags = F_ZOMBIE; 1027 return; 1028 } 1029 1030 finalize: 1031 SPLAY_REMOVE(sessiontree, &env->sc_sessions, s); 1032 bzero(s, sizeof(*s)); 1033 free(s); 1034 } 1035 1036 int 1037 session_cmp(struct session *s1, struct session *s2) 1038 { 1039 /* 1040 * do not return u_int64_t's 1041 */ 1042 if (s1->s_id < s2->s_id) 1043 return (-1); 1044 1045 if (s1->s_id > s2->s_id) 1046 return (1); 1047 1048 return (0); 1049 } 1050 1051 static int 1052 session_set_mailaddr(struct mailaddr *maddr, char *line) 1053 { 1054 size_t len; 1055 1056 len = strlen(line); 1057 if (*line != '<' || line[len - 1] != '>') 1058 return 0; 1059 line[len - 1] = '\0'; 1060 1061 return email_to_mailaddr(maddr, line + 1); 1062 } 1063 1064 void 1065 session_respond(struct session *s, char *fmt, ...) 1066 { 1067 va_list ap; 1068 int n, delay; 1069 char buf[SMTP_LINE_MAX]; 1070 1071 va_start(ap, fmt); 1072 n = vsnprintf(buf, sizeof buf, fmt, ap); 1073 va_end(ap); 1074 if (n == -1 || n >= SMTP_LINE_MAX) 1075 fatal("session_respond: line too long"); 1076 if (n < 4) 1077 fatal("session_respond: response too short"); 1078 1079 log_trace(TRACE_SMTP, "smtp: %p: >>> %s", s, buf); 1080 1081 iobuf_queue(&s->s_iobuf, buf, n); 1082 iobuf_queue(&s->s_iobuf, "\r\n", 2); 1083 1084 /* 1085 * Log failures. Might be annoying in the long term, but it is a good 1086 * development aid for now. 1087 */ 1088 switch (buf[0]) { 1089 case '5': 1090 case '4': 1091 log_info("%08x: from=<%s@%s>, relay=%s [%s], stat=LocalError (%.*s)", 1092 evpid_to_msgid(s->s_msg.id), 1093 s->s_msg.sender.user, s->s_msg.sender.domain, 1094 s->s_hostname, ss_to_text(&s->s_ss), 1095 n, buf); 1096 break; 1097 } 1098 1099 /* Detect multi-line response. */ 1100 switch (buf[3]) { 1101 case '-': 1102 return; 1103 case ' ': 1104 break; 1105 default: 1106 fatalx("session_respond: invalid response"); 1107 } 1108 1109 /* 1110 * Deal with request flooding; avoid letting response rate keep up 1111 * with incoming request rate. 1112 */ 1113 s->s_nresp[s->s_state]++; 1114 1115 if (s->s_state == S_RCPT) 1116 delay = 0; 1117 else if ((n = s->s_nresp[s->s_state] - FAST_RESPONSES) > 0) 1118 delay = MIN(1 << (n - 1), MAX_RESPONSE_DELAY); 1119 else 1120 delay = 0; 1121 1122 if (delay > 0) { 1123 struct timeval tv = { delay, 0 }; 1124 1125 io_pause(&s->s_io, IO_PAUSE_OUT); 1126 env->stats->smtp.delays++; 1127 1128 /* in case session_respond is called multiple times */ 1129 evtimer_del(&s->s_ev); 1130 evtimer_set(&s->s_ev, session_respond_delayed, s); 1131 evtimer_add(&s->s_ev, &tv); 1132 } 1133 } 1134 1135 static void 1136 session_respond_delayed(int fd, short event, void *p) 1137 { 1138 struct session *s = p; 1139 1140 io_resume(&s->s_io, IO_PAUSE_OUT); 1141 } 1142 1143 /* 1144 * Send IMSG, waiting for reply safely. 1145 */ 1146 static void 1147 session_imsg(struct session *s, enum smtp_proc_type proc, enum imsg_type type, 1148 u_int32_t peerid, pid_t pid, int fd, void *data, u_int16_t datalen) 1149 { 1150 /* 1151 * Each outgoing IMSG has a response IMSG associated that must be 1152 * waited for before the session can be progressed further. 1153 * During the wait period: 1154 * 1) session must not be destroyed, 1155 * 2) session must not be read from, 1156 * 3) session may be written to. 1157 */ 1158 1159 s->s_flags |= F_WAITIMSG; 1160 imsg_compose_event(env->sc_ievs[proc], type, peerid, pid, fd, data, 1161 datalen); 1162 } 1163 1164 SPLAY_GENERATE(sessiontree, session, s_nodes, session_cmp); 1165 1166 #define CASE(x) case x : return #x 1167 1168 const char * 1169 session_strstate(int state) 1170 { 1171 static char buf[32]; 1172 1173 switch (state) { 1174 CASE(S_NEW); 1175 CASE(S_CONNECTED); 1176 CASE(S_INIT); 1177 CASE(S_GREETED); 1178 CASE(S_TLS); 1179 CASE(S_AUTH_INIT); 1180 CASE(S_AUTH_USERNAME); 1181 CASE(S_AUTH_PASSWORD); 1182 CASE(S_AUTH_FINALIZE); 1183 CASE(S_RSET); 1184 CASE(S_HELO); 1185 CASE(S_MAIL_MFA); 1186 CASE(S_MAIL_QUEUE); 1187 CASE(S_MAIL); 1188 CASE(S_RCPT_MFA); 1189 CASE(S_RCPT); 1190 CASE(S_DATA); 1191 CASE(S_DATA_QUEUE); 1192 CASE(S_DATACONTENT); 1193 CASE(S_DONE); 1194 CASE(S_QUIT); 1195 CASE(S_CLOSE); 1196 default: 1197 snprintf(buf, sizeof(buf), "S_??? (%d)", state); 1198 return buf; 1199 } 1200 } 1201