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