1 /* $OpenBSD: mta.c,v 1.44 2009/04/28 21:56:36 gilles Exp $ */ 2 3 /* 4 * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> 5 * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/types.h> 21 #include <sys/queue.h> 22 #include <sys/tree.h> 23 #include <sys/param.h> 24 #include <sys/socket.h> 25 26 #include <netinet/in.h> 27 #include <arpa/inet.h> 28 29 #include <ssl/ssl.h> 30 31 #include <errno.h> 32 #include <event.h> 33 #include <pwd.h> 34 #include <signal.h> 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #include <unistd.h> 39 40 #include "smtpd.h" 41 42 __dead void mta_shutdown(void); 43 void mta_sig_handler(int, short, void *); 44 void mta_dispatch_parent(int, short, void *); 45 void mta_dispatch_queue(int, short, void *); 46 void mta_dispatch_runner(int, short, void *); 47 void mta_dispatch_lka(int, short, void *); 48 void mta_setup_events(struct smtpd *); 49 void mta_disable_events(struct smtpd *); 50 void mta_write(int, short, void *); 51 int mta_connect(struct session *); 52 void mta_read_handler(struct bufferevent *, void *); 53 void mta_write_handler(struct bufferevent *, void *); 54 void mta_error_handler(struct bufferevent *, short, void *); 55 int mta_reply_handler(struct bufferevent *, void *); 56 void mta_batch_update_queue(struct batch *); 57 void mta_mxlookup(struct smtpd *, struct session *, char *, struct rule *); 58 void ssl_client_init(struct session *); 59 60 void 61 mta_sig_handler(int sig, short event, void *p) 62 { 63 switch (sig) { 64 case SIGINT: 65 case SIGTERM: 66 mta_shutdown(); 67 break; 68 default: 69 fatalx("mta_sig_handler: unexpected signal"); 70 } 71 } 72 73 void 74 mta_dispatch_parent(int sig, short event, void *p) 75 { 76 struct smtpd *env = p; 77 struct imsgbuf *ibuf; 78 struct imsg imsg; 79 ssize_t n; 80 81 ibuf = env->sc_ibufs[PROC_PARENT]; 82 switch (event) { 83 case EV_READ: 84 if ((n = imsg_read(ibuf)) == -1) 85 fatal("imsg_read_error"); 86 if (n == 0) { 87 /* this pipe is dead, so remove the event handler */ 88 event_del(&ibuf->ev); 89 event_loopexit(NULL); 90 return; 91 } 92 break; 93 case EV_WRITE: 94 if (msgbuf_write(&ibuf->w) == -1) 95 fatal("msgbuf_write"); 96 imsg_event_add(ibuf); 97 return; 98 default: 99 fatalx("unknown event"); 100 } 101 102 for (;;) { 103 if ((n = imsg_get(ibuf, &imsg)) == -1) 104 fatalx("mta_dispatch_parent: imsg_get error"); 105 if (n == 0) 106 break; 107 108 switch (imsg.hdr.type) { 109 default: 110 log_warnx("mta_dispatch_parent: got imsg %d", 111 imsg.hdr.type); 112 fatalx("mta_dispatch_parent: unexpected imsg"); 113 } 114 imsg_free(&imsg); 115 } 116 imsg_event_add(ibuf); 117 } 118 119 void 120 mta_dispatch_lka(int sig, short event, void *p) 121 { 122 struct smtpd *env = p; 123 struct imsgbuf *ibuf; 124 struct imsg imsg; 125 ssize_t n; 126 127 ibuf = env->sc_ibufs[PROC_LKA]; 128 switch (event) { 129 case EV_READ: 130 if ((n = imsg_read(ibuf)) == -1) 131 fatal("imsg_read_error"); 132 if (n == 0) { 133 /* this pipe is dead, so remove the event handler */ 134 event_del(&ibuf->ev); 135 event_loopexit(NULL); 136 return; 137 } 138 break; 139 case EV_WRITE: 140 if (msgbuf_write(&ibuf->w) == -1) 141 fatal("msgbuf_write"); 142 imsg_event_add(ibuf); 143 return; 144 default: 145 fatalx("unknown event"); 146 } 147 148 for (;;) { 149 if ((n = imsg_get(ibuf, &imsg)) == -1) 150 fatalx("mta_dispatch_lka: imsg_get error"); 151 if (n == 0) 152 break; 153 154 switch (imsg.hdr.type) { 155 case IMSG_LKA_MX: { 156 struct session key; 157 struct mxrep *mxrep; 158 struct session *s; 159 struct mxhost *mxhost; 160 161 mxrep = imsg.data; 162 key.s_id = mxrep->id; 163 164 s = SPLAY_FIND(sessiontree, &env->sc_sessions, &key); 165 if (s == NULL) 166 fatal("mta_dispatch_lka: session is gone"); 167 168 mxhost = calloc(1, sizeof(struct mxhost)); 169 if (mxhost == NULL) 170 fatal("mta_dispatch_lka: calloc"); 171 172 *mxhost = mxrep->mxhost; 173 TAILQ_INSERT_TAIL(&s->mxhosts, mxhost, entry); 174 175 break; 176 } 177 case IMSG_LKA_MX_END: { 178 struct session key; 179 struct mxrep *mxrep; 180 struct session *s; 181 int ret; 182 183 mxrep = imsg.data; 184 key.s_id = mxrep->id; 185 186 s = SPLAY_FIND(sessiontree, &env->sc_sessions, &key); 187 if (s == NULL) 188 fatal("smtp_dispatch_parent: session is gone"); 189 190 s->batch->flags |= F_BATCH_RESOLVED; 191 192 do { 193 ret = mta_connect(s); 194 } while (ret == 0); 195 196 if (ret < 0) { 197 mta_batch_update_queue(s->batch); 198 session_destroy(s); 199 } 200 201 break; 202 } 203 default: 204 log_warnx("mta_dispatch_parent: got imsg %d", 205 imsg.hdr.type); 206 fatalx("mta_dispatch_lka: unexpected imsg"); 207 } 208 imsg_free(&imsg); 209 } 210 imsg_event_add(ibuf); 211 } 212 213 void 214 mta_dispatch_queue(int sig, short event, void *p) 215 { 216 struct smtpd *env = p; 217 struct imsgbuf *ibuf; 218 struct imsg imsg; 219 ssize_t n; 220 221 ibuf = env->sc_ibufs[PROC_QUEUE]; 222 switch (event) { 223 case EV_READ: 224 if ((n = imsg_read(ibuf)) == -1) 225 fatal("imsg_read_error"); 226 if (n == 0) { 227 /* this pipe is dead, so remove the event handler */ 228 event_del(&ibuf->ev); 229 event_loopexit(NULL); 230 return; 231 } 232 break; 233 case EV_WRITE: 234 if (msgbuf_write(&ibuf->w) == -1) 235 fatal("msgbuf_write"); 236 imsg_event_add(ibuf); 237 return; 238 default: 239 fatalx("unknown event"); 240 } 241 242 for (;;) { 243 if ((n = imsg_get(ibuf, &imsg)) == -1) 244 fatalx("mta_dispatch_queue: imsg_get error"); 245 if (n == 0) 246 break; 247 248 switch (imsg.hdr.type) { 249 case IMSG_QUEUE_MESSAGE_FD: { 250 struct batch *batchp; 251 struct session *sessionp; 252 int fd; 253 254 if ((fd = imsg_get_fd(ibuf, &imsg)) == -1) { 255 /* NEEDS_FIX - unsure yet how it must be handled */ 256 fatalx("mta_dispatch_queue: imsg_get_fd"); 257 } 258 259 batchp = (struct batch *)imsg.data; 260 batchp = batch_by_id(env, batchp->id); 261 sessionp = batchp->sessionp; 262 263 if ((batchp->messagefp = fdopen(fd, "r")) == NULL) 264 fatal("mta_dispatch_queue: fdopen"); 265 266 session_respond(sessionp, "DATA"); 267 bufferevent_enable(sessionp->s_bev, EV_READ); 268 break; 269 } 270 default: 271 log_warnx("mta_dispatch_queue: got imsg %d", 272 imsg.hdr.type); 273 fatalx("mta_dispatch_queue: unexpected imsg"); 274 } 275 imsg_free(&imsg); 276 } 277 imsg_event_add(ibuf); 278 } 279 280 void 281 mta_dispatch_runner(int sig, short event, void *p) 282 { 283 struct smtpd *env = p; 284 struct imsgbuf *ibuf; 285 struct imsg imsg; 286 ssize_t n; 287 288 ibuf = env->sc_ibufs[PROC_RUNNER]; 289 switch (event) { 290 case EV_READ: 291 if ((n = imsg_read(ibuf)) == -1) 292 fatal("imsg_read_error"); 293 if (n == 0) { 294 /* this pipe is dead, so remove the event handler */ 295 event_del(&ibuf->ev); 296 event_loopexit(NULL); 297 return; 298 } 299 break; 300 case EV_WRITE: 301 if (msgbuf_write(&ibuf->w) == -1) 302 fatal("msgbuf_write"); 303 imsg_event_add(ibuf); 304 return; 305 default: 306 fatalx("unknown event"); 307 } 308 309 for (;;) { 310 if ((n = imsg_get(ibuf, &imsg)) == -1) 311 fatalx("mta_dispatch_runner: imsg_get error"); 312 if (n == 0) 313 break; 314 315 switch (imsg.hdr.type) { 316 case IMSG_BATCH_CREATE: { 317 struct session *s; 318 struct batch *batchp; 319 320 /* create a client session */ 321 if ((s = calloc(1, sizeof(*s))) == NULL) 322 fatal(NULL); 323 s->s_state = S_INIT; 324 s->s_env = env; 325 s->s_id = queue_generate_id(); 326 TAILQ_INIT(&s->mxhosts); 327 SPLAY_INSERT(sessiontree, &s->s_env->sc_sessions, s); 328 329 /* create the batch for this session */ 330 batchp = calloc(1, sizeof (struct batch)); 331 if (batchp == NULL) 332 fatal("mta_dispatch_runner: calloc"); 333 334 *batchp = *(struct batch *)imsg.data; 335 batchp->session_id = s->s_id; 336 batchp->env = env; 337 batchp->flags = 0; 338 batchp->sessionp = s; 339 340 s->batch = batchp; 341 342 TAILQ_INIT(&batchp->messages); 343 SPLAY_INSERT(batchtree, &env->batch_queue, batchp); 344 345 break; 346 } 347 case IMSG_BATCH_APPEND: { 348 struct batch *batchp; 349 struct message *messagep; 350 351 messagep = calloc(1, sizeof (struct message)); 352 if (messagep == NULL) 353 fatal("mta_dispatch_runner: calloc"); 354 355 *messagep = *(struct message *)imsg.data; 356 357 batchp = batch_by_id(env, messagep->batch_id); 358 if (batchp == NULL) 359 fatalx("mta_dispatch_runner: internal inconsistency."); 360 361 batchp->session_ss = messagep->session_ss; 362 strlcpy(batchp->session_hostname, 363 messagep->session_hostname, 364 sizeof(batchp->session_hostname)); 365 strlcpy(batchp->session_helo, messagep->session_helo, 366 sizeof(batchp->session_helo)); 367 368 TAILQ_INSERT_TAIL(&batchp->messages, messagep, entry); 369 break; 370 } 371 case IMSG_BATCH_CLOSE: { 372 struct batch *batchp; 373 struct session *s; 374 375 batchp = (struct batch *)imsg.data; 376 batchp = batch_by_id(env, batchp->id); 377 if (batchp == NULL) 378 fatalx("mta_dispatch_runner: internal inconsistency."); 379 380 batchp->flags |= F_BATCH_COMPLETE; 381 382 /* assume temporary failure by default, safest choice */ 383 batchp->status = S_BATCH_TEMPFAILURE; 384 385 log_debug("batch ready, we can initiate a session"); 386 387 s = batchp->sessionp; 388 389 mta_mxlookup(env, s, batchp->hostname, &batchp->rule); 390 391 break; 392 } 393 default: 394 log_warnx("mta_dispatch_runner: got imsg %d", 395 imsg.hdr.type); 396 fatalx("mta_dispatch_runner: unexpected imsg"); 397 } 398 imsg_free(&imsg); 399 } 400 imsg_event_add(ibuf); 401 } 402 403 void 404 mta_shutdown(void) 405 { 406 log_info("mail transfer agent exiting"); 407 _exit(0); 408 } 409 410 void 411 mta_setup_events(struct smtpd *env) 412 { 413 } 414 415 void 416 mta_disable_events(struct smtpd *env) 417 { 418 } 419 420 pid_t 421 mta(struct smtpd *env) 422 { 423 pid_t pid; 424 425 struct passwd *pw; 426 struct event ev_sigint; 427 struct event ev_sigterm; 428 429 struct peer peers[] = { 430 { PROC_QUEUE, mta_dispatch_queue }, 431 { PROC_RUNNER, mta_dispatch_runner }, 432 { PROC_LKA, mta_dispatch_lka } 433 }; 434 435 switch (pid = fork()) { 436 case -1: 437 fatal("mta: cannot fork"); 438 case 0: 439 break; 440 default: 441 return (pid); 442 } 443 444 ssl_init(); 445 purge_config(env, PURGE_EVERYTHING); 446 447 pw = env->sc_pw; 448 #ifndef DEBUG 449 if (chroot(pw->pw_dir) == -1) 450 fatal("mta: chroot"); 451 if (chdir("/") == -1) 452 fatal("mta: chdir(\"/\")"); 453 #else 454 #warning disabling privilege revocation and chroot in DEBUG MODE 455 #endif 456 457 setproctitle("mail transfer agent"); 458 smtpd_process = PROC_MTA; 459 460 #ifndef DEBUG 461 if (setgroups(1, &pw->pw_gid) || 462 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 463 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 464 fatal("mta: cannot drop privileges"); 465 #endif 466 467 event_init(); 468 469 signal_set(&ev_sigint, SIGINT, mta_sig_handler, env); 470 signal_set(&ev_sigterm, SIGTERM, mta_sig_handler, env); 471 signal_add(&ev_sigint, NULL); 472 signal_add(&ev_sigterm, NULL); 473 signal(SIGPIPE, SIG_IGN); 474 signal(SIGHUP, SIG_IGN); 475 476 config_pipes(env, peers, 3); 477 config_peers(env, peers, 3); 478 479 SPLAY_INIT(&env->batch_queue); 480 481 mta_setup_events(env); 482 event_dispatch(); 483 mta_shutdown(); 484 485 return (0); 486 } 487 488 void 489 mta_mxlookup(struct smtpd *env, struct session *sessionp, char *hostname, struct rule *rule) 490 { 491 struct mxreq mxreq; 492 493 mxreq.id = sessionp->s_id; 494 mxreq.rule = *rule; 495 (void)strlcpy(mxreq.hostname, hostname, MAXHOSTNAMELEN); 496 imsg_compose(env->sc_ibufs[PROC_LKA], IMSG_LKA_MX, 0, 0, -1, 497 &mxreq, sizeof(struct mxreq)); 498 } 499 500 /* shamelessly ripped usr.sbin/relayd/check_tcp.c ;) */ 501 int 502 mta_connect(struct session *sessionp) 503 { 504 int s; 505 int type; 506 struct linger lng; 507 struct sockaddr_in ssin; 508 struct sockaddr_in6 ssin6; 509 struct mxhost *mxhost; 510 511 mxhost = TAILQ_FIRST(&sessionp->mxhosts); 512 if (mxhost == NULL) 513 return -1; 514 515 if ((s = socket(mxhost->ss.ss_family, SOCK_STREAM, 0)) == -1) 516 goto bad; 517 518 bzero(&lng, sizeof(lng)); 519 if (setsockopt(s, SOL_SOCKET, SO_LINGER, &lng, sizeof (lng)) == -1) 520 goto bad; 521 522 type = 1; 523 if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &type, sizeof (type)) == -1) 524 goto bad; 525 526 session_socket_blockmode(s, BM_NONBLOCK); 527 528 if (mxhost->ss.ss_family == PF_INET) { 529 ssin = *(struct sockaddr_in *)&mxhost->ss; 530 if (connect(s, (struct sockaddr *)&ssin, sizeof(struct sockaddr_in)) == -1) 531 if (errno != EINPROGRESS) 532 goto bad; 533 } 534 535 if (mxhost->ss.ss_family == PF_INET6) { 536 ssin6 = *(struct sockaddr_in6 *)&mxhost->ss; 537 if (connect(s, (struct sockaddr *)&ssin6, sizeof(struct sockaddr_in6)) == -1) 538 if (errno != EINPROGRESS) 539 goto bad; 540 } 541 542 sessionp->s_tv.tv_sec = SMTPD_CONNECT_TIMEOUT; 543 sessionp->s_tv.tv_usec = 0; 544 sessionp->s_fd = s; 545 event_set(&sessionp->s_ev, s, EV_TIMEOUT|EV_WRITE, mta_write, sessionp); 546 event_add(&sessionp->s_ev, &sessionp->s_tv); 547 548 return 1; 549 550 bad: 551 if (mxhost) { 552 TAILQ_REMOVE(&sessionp->mxhosts, mxhost, entry); 553 free(mxhost); 554 } 555 close(s); 556 return 0; 557 } 558 559 void 560 mta_write(int s, short event, void *arg) 561 { 562 struct session *sessionp = arg; 563 struct batch *batchp = sessionp->batch; 564 struct mxhost *mxhost; 565 int ret; 566 567 mxhost = TAILQ_FIRST(&sessionp->mxhosts); 568 569 if (event == EV_TIMEOUT) { 570 571 if (mxhost) { 572 TAILQ_REMOVE(&sessionp->mxhosts, mxhost, entry); 573 free(mxhost); 574 } 575 close(s); 576 577 if (sessionp->s_bev) { 578 bufferevent_free(sessionp->s_bev); 579 sessionp->s_bev = NULL; 580 } 581 strlcpy(batchp->errorline, "connection timed-out.", 582 sizeof(batchp->errorline)); 583 584 do { 585 ret = mta_connect(sessionp); 586 } while (ret == 0); 587 588 if (ret < 0) { 589 mta_batch_update_queue(batchp); 590 session_destroy(sessionp); 591 } 592 593 return; 594 } 595 596 sessionp->s_bev = bufferevent_new(s, mta_read_handler, mta_write_handler, 597 mta_error_handler, sessionp); 598 599 if (sessionp->s_bev == NULL) { 600 mta_batch_update_queue(batchp); 601 session_destroy(sessionp); 602 return; 603 } 604 605 if (mxhost && mxhost->flags & F_SMTPS) { 606 ssl_client_init(sessionp); 607 return; 608 } 609 bufferevent_enable(sessionp->s_bev, EV_READ); 610 } 611 612 void 613 mta_read_handler(struct bufferevent *bev, void *arg) 614 { 615 while (mta_reply_handler(bev, arg)) 616 ; 617 } 618 619 int 620 mta_reply_handler(struct bufferevent *bev, void *arg) 621 { 622 struct session *sessionp = arg; 623 struct batch *batchp = sessionp->batch; 624 struct smtpd *env = batchp->env; 625 struct message *messagep = NULL; 626 char *line; 627 int i; 628 int code; 629 #define F_ISINFO 0x1 630 #define F_ISPROTOERROR 0x2 631 char codebuf[4]; 632 const char *errstr; 633 int flags = 0; 634 struct mxhost *mxhost = TAILQ_FIRST(&sessionp->mxhosts); 635 636 line = evbuffer_readline(bev->input); 637 if (line == NULL) 638 return 0; 639 640 log_debug("remote server sent: [%s]", line); 641 642 strlcpy(codebuf, line, sizeof(codebuf)); 643 code = strtonum(codebuf, 0, UINT16_MAX, &errstr); 644 if (errstr || code < 100) { 645 /* Server sent invalid line, protocol error */ 646 batchp->status = S_BATCH_PERMFAILURE; 647 strlcpy(batchp->errorline, line, sizeof(batchp->errorline)); 648 mta_batch_update_queue(batchp); 649 session_destroy(sessionp); 650 return 0; 651 } 652 653 if (line[3] == '-') { 654 if (strcasecmp(&line[4], "STARTTLS") == 0) 655 sessionp->s_flags |= F_PEERHASTLS; 656 else if (strncasecmp(&line[4], "AUTH ", 5) == 0 || 657 strncasecmp(&line[4], "AUTH-", 5) == 0) 658 sessionp->s_flags |= F_PEERHASAUTH; 659 return 1; 660 } 661 662 switch (code) { 663 case 250: 664 if (sessionp->s_state == S_DONE) { 665 batchp->status = S_BATCH_ACCEPTED; 666 mta_batch_update_queue(batchp); 667 session_destroy(sessionp); 668 return 0; 669 } 670 671 if (sessionp->s_state == S_GREETED && 672 (sessionp->s_flags & F_PEERHASTLS) && 673 !(sessionp->s_flags & F_SECURE)) { 674 session_respond(sessionp, "STARTTLS"); 675 sessionp->s_state = S_TLS; 676 return 0; 677 } 678 679 if (sessionp->s_state == S_GREETED && 680 (sessionp->s_flags & F_PEERHASAUTH) && 681 (sessionp->s_flags & F_SECURE) && 682 (mxhost->flags & F_AUTH) && 683 (mxhost->credentials[0] != '\0')) { 684 log_debug("AUTH PLAIN %s", mxhost->credentials); 685 session_respond(sessionp, "AUTH PLAIN %s", 686 mxhost->credentials); 687 sessionp->s_state = S_AUTH_INIT; 688 return 0; 689 } 690 691 if (sessionp->s_state == S_GREETED && 692 !(sessionp->s_flags & F_PEERHASTLS) && 693 mxhost->flags & F_STARTTLS) { 694 /* PERM - we want TLS but it is not advertised */ 695 batchp->status = S_BATCH_PERMFAILURE; 696 mta_batch_update_queue(batchp); 697 session_destroy(sessionp); 698 return 0; 699 } 700 701 if (sessionp->s_state == S_GREETED && 702 !(sessionp->s_flags & F_PEERHASAUTH) && 703 mxhost->flags & F_AUTH) { 704 /* PERM - we want AUTH but it is not advertised */ 705 batchp->status = S_BATCH_PERMFAILURE; 706 mta_batch_update_queue(batchp); 707 session_destroy(sessionp); 708 return 0; 709 } 710 711 break; 712 713 case 220: 714 if (sessionp->s_state == S_TLS) { 715 ssl_client_init(sessionp); 716 bufferevent_disable(bev, EV_READ|EV_WRITE); 717 sessionp->s_state = S_GREETED; 718 return 0; 719 } 720 721 session_respond(sessionp, "EHLO %s", env->sc_hostname); 722 sessionp->s_state = S_GREETED; 723 return 1; 724 725 case 235: 726 if (sessionp->s_state == S_AUTH_INIT) { 727 sessionp->s_flags |= F_AUTHENTICATED; 728 sessionp->s_state = S_GREETED; 729 break; 730 } 731 return 0; 732 case 421: 733 case 450: 734 case 451: 735 strlcpy(batchp->errorline, line, sizeof(batchp->errorline)); 736 mta_batch_update_queue(batchp); 737 session_destroy(sessionp); 738 return 0; 739 740 /* The following codes are state dependant and will cause 741 * a batch rejection if returned at the wrong state. 742 */ 743 case 530: 744 case 550: 745 if (sessionp->s_state == S_RCPT) { 746 batchp->messagep->status = (S_MESSAGE_REJECTED|S_MESSAGE_PERMFAILURE); 747 strlcpy(batchp->messagep->session_errorline, line, 748 sizeof(batchp->messagep->session_errorline)); 749 break; 750 } 751 case 354: 752 if (sessionp->s_state == S_RCPT && batchp->messagep == NULL) { 753 sessionp->s_state = S_DATA; 754 break; 755 } 756 757 case 221: 758 if (sessionp->s_state == S_DONE) { 759 batchp->status = S_BATCH_ACCEPTED; 760 mta_batch_update_queue(batchp); 761 session_destroy(sessionp); 762 return 0; 763 } 764 765 case 535: 766 /* Authentication failed*/ 767 case 552: 768 case 553: 769 flags |= F_ISPROTOERROR; 770 default: 771 /* Server sent code we know nothing about, error */ 772 if (!(flags & F_ISPROTOERROR)) 773 log_warn("SMTP session returned unknown status %d.", code); 774 775 strlcpy(batchp->errorline, line, sizeof(batchp->errorline)); 776 mta_batch_update_queue(batchp); 777 session_destroy(sessionp); 778 return 0; 779 } 780 781 782 switch (sessionp->s_state) { 783 case S_GREETED: { 784 char *user; 785 char *domain; 786 787 if (batchp->type & T_DAEMON_BATCH) { 788 user = "MAILER-DAEMON"; 789 domain = env->sc_hostname; 790 } 791 else { 792 messagep = TAILQ_FIRST(&batchp->messages); 793 user = messagep->sender.user; 794 domain = messagep->sender.domain; 795 } 796 797 if (user[0] == '\0' && domain[0] == '\0') 798 session_respond(sessionp, "MAIL FROM:<>"); 799 else 800 session_respond(sessionp, "MAIL FROM:<%s@%s>", user, domain); 801 802 sessionp->s_state = S_MAIL; 803 804 break; 805 } 806 807 case S_MAIL: 808 sessionp->s_state = S_RCPT; 809 810 case S_RCPT: { 811 char *user; 812 char *domain; 813 814 /* Is this the first RCPT ? */ 815 if (batchp->messagep == NULL) 816 messagep = TAILQ_FIRST(&batchp->messages); 817 else { 818 /* We already had a RCPT, mark is as accepted and 819 * fetch next one from queue if we aren't dealing 820 * with a daemon batch. 821 */ 822 if (batchp->type & T_DAEMON_BATCH) 823 messagep = NULL; 824 else { 825 messagep = batchp->messagep; 826 if ((messagep->status & S_MESSAGE_REJECTED) == 0) 827 messagep->status = S_MESSAGE_ACCEPTED; 828 messagep = TAILQ_NEXT(batchp->messagep, entry); 829 } 830 } 831 batchp->messagep = messagep; 832 833 if (messagep) { 834 if (batchp->type & T_DAEMON_BATCH) { 835 user = messagep->sender.user; 836 domain = messagep->sender.domain; 837 } 838 else { 839 user = messagep->recipient.user; 840 domain = messagep->recipient.domain; 841 } 842 session_respond(sessionp, "RCPT TO:<%s@%s>", user, domain); 843 } 844 else { 845 /* Do we have at least one accepted recipient ? */ 846 if ((batchp->type & T_DAEMON_BATCH) == 0) { 847 TAILQ_FOREACH(messagep, &batchp->messages, entry) { 848 if (messagep->status & S_MESSAGE_ACCEPTED) 849 break; 850 } 851 if (messagep == NULL) { 852 batchp->status = S_BATCH_PERMFAILURE; 853 mta_batch_update_queue(batchp); 854 session_destroy(sessionp); 855 return 0; 856 } 857 } 858 859 imsg_compose(env->sc_ibufs[PROC_QUEUE], IMSG_QUEUE_MESSAGE_FD, 860 0, 0, -1, batchp, sizeof(*batchp)); 861 bufferevent_disable(sessionp->s_bev, EV_READ); 862 } 863 break; 864 } 865 866 case S_DATA: { 867 session_respond(sessionp, "Received: from %s (%s [%s])", 868 batchp->session_helo, batchp->session_hostname, 869 ss_to_text(&batchp->session_ss)); 870 871 session_respond(sessionp, "\tby %s with ESMTP id %s;", 872 batchp->env->sc_hostname, batchp->message_id); 873 874 session_respond(sessionp, "\t%s", time_to_text(batchp->creation)); 875 876 if (sessionp->s_flags & F_SECURE) { 877 log_info("%s: version=%s cipher=%s bits=%d", 878 batchp->message_id, 879 SSL_get_cipher_version(sessionp->s_ssl), 880 SSL_get_cipher_name(sessionp->s_ssl), 881 SSL_get_cipher_bits(sessionp->s_ssl, NULL)); 882 } 883 884 TAILQ_FOREACH(messagep, &batchp->messages, entry) { 885 session_respond(sessionp, "X-OpenSMTPD-Loop: %s@%s", 886 messagep->session_rcpt.user, 887 messagep->session_rcpt.domain); 888 } 889 890 if (batchp->type & T_DAEMON_BATCH) { 891 session_respond(sessionp, "Hi !"); 892 session_respond(sessionp, "%s", ""); 893 session_respond(sessionp, "This is the MAILER-DAEMON, please DO NOT REPLY to this e-mail it is"); 894 session_respond(sessionp, "just a notification to let you know that an error has occured."); 895 session_respond(sessionp, "%s", ""); 896 897 if (batchp->status == S_BATCH_PERMFAILURE) { 898 session_respond(sessionp, "You ran into a PERMANENT FAILURE, which means that the e-mail can't"); 899 session_respond(sessionp, "be delivered to the remote host no matter how much I'll try."); 900 session_respond(sessionp, "%s", ""); 901 session_respond(sessionp, "Diagnostic:"); 902 session_respond(sessionp, "%s", batchp->errorline); 903 session_respond(sessionp, "%s", ""); 904 } 905 906 if (batchp->status == S_BATCH_TEMPFAILURE) { 907 session_respond(sessionp, "You ran into a TEMPORARY FAILURE, which means that the e-mail can't"); 908 session_respond(sessionp, "be delivered right now, but could be deliberable at a later time. I"); 909 session_respond(sessionp, "will attempt until it succeeds for the next four days, then let you"); 910 session_respond(sessionp, "know if it didn't work out."); 911 session_respond(sessionp, "%s", ""); 912 session_respond(sessionp, "Diagnostic:"); 913 session_respond(sessionp, "%s", batchp->errorline); 914 session_respond(sessionp, "%s", ""); 915 } 916 917 i = 0; 918 TAILQ_FOREACH(messagep, &batchp->messages, entry) { 919 if (messagep->status & S_MESSAGE_TEMPFAILURE) { 920 if (i == 0) { 921 session_respond(sessionp, "The following recipients caused a temporary failure:"); 922 ++i; 923 } 924 925 session_respond(sessionp, 926 "\t<%s@%s>:", messagep->recipient.user, messagep->recipient.domain); 927 session_respond(sessionp, 928 "%s", messagep->session_errorline); 929 session_respond(sessionp, "%s", ""); 930 } 931 } 932 933 i = 0; 934 TAILQ_FOREACH(messagep, &batchp->messages, entry) { 935 if (messagep->status & S_MESSAGE_PERMFAILURE) { 936 if (i == 0) { 937 session_respond(sessionp, 938 "The following recipients caused a permanent failure:"); 939 ++i; 940 } 941 942 session_respond(sessionp, 943 "\t<%s@%s>:", messagep->recipient.user, messagep->recipient.domain); 944 session_respond(sessionp, 945 "%s", messagep->session_errorline); 946 session_respond(sessionp, "%s", ""); 947 } 948 } 949 950 session_respond(sessionp, "Below is a copy of the original message:"); 951 session_respond(sessionp, "%s", ""); 952 } 953 954 break; 955 } 956 case S_DONE: 957 session_respond(sessionp, "QUIT"); 958 sessionp->s_state = S_QUIT; 959 break; 960 961 default: 962 log_info("unknown command: %d", sessionp->s_state); 963 } 964 965 return 1; 966 } 967 968 void 969 mta_write_handler(struct bufferevent *bev, void *arg) 970 { 971 struct session *sessionp = arg; 972 struct batch *batchp = sessionp->batch; 973 char *buf, *lbuf; 974 size_t len; 975 976 if (sessionp->s_state == S_QUIT) { 977 bufferevent_disable(bev, EV_READ|EV_WRITE); 978 log_debug("closing connection because of QUIT"); 979 close(sessionp->s_fd); 980 return; 981 } 982 983 /* Progressively fill the output buffer with data */ 984 if (sessionp->s_state == S_DATA) { 985 986 lbuf = NULL; 987 if ((buf = fgetln(batchp->messagefp, &len))) { 988 if (buf[len - 1] == '\n') 989 buf[len - 1] = '\0'; 990 else { 991 if ((lbuf = malloc(len + 1)) == NULL) 992 fatal("mta_write_handler: malloc"); 993 memcpy(lbuf, buf, len); 994 lbuf[len] = '\0'; 995 buf = lbuf; 996 } 997 998 /* "If first character of the line is a period, one 999 * additional period is inserted at the beginning." 1000 * [4.5.2] 1001 */ 1002 if (*buf == '.') 1003 evbuffer_add_printf(sessionp->s_bev->output, "."); 1004 1005 session_respond(sessionp, "%s", buf); 1006 free(lbuf); 1007 lbuf = NULL; 1008 } 1009 else { 1010 session_respond(sessionp, "."); 1011 sessionp->s_state = S_DONE; 1012 fclose(batchp->messagefp); 1013 batchp->messagefp = NULL; 1014 } 1015 } 1016 } 1017 1018 void 1019 mta_error_handler(struct bufferevent *bev, short error, void *arg) 1020 { 1021 struct session *sessionp = arg; 1022 1023 if (error & (EVBUFFER_TIMEOUT|EVBUFFER_EOF)) { 1024 bufferevent_disable(bev, EV_READ|EV_WRITE); 1025 log_debug("closing connection because of an error"); 1026 close(sessionp->s_fd); 1027 return; 1028 } 1029 } 1030 1031 void 1032 mta_batch_update_queue(struct batch *batchp) 1033 { 1034 struct smtpd *env = batchp->env; 1035 struct message *messagep; 1036 1037 while ((messagep = TAILQ_FIRST(&batchp->messages)) != NULL) { 1038 1039 if (batchp->status == S_BATCH_PERMFAILURE) { 1040 messagep->status |= S_MESSAGE_PERMFAILURE; 1041 } 1042 1043 if (batchp->status == S_BATCH_TEMPFAILURE) { 1044 if (messagep->status != S_MESSAGE_PERMFAILURE) 1045 messagep->status |= S_MESSAGE_TEMPFAILURE; 1046 } 1047 1048 if ((messagep->status & S_MESSAGE_TEMPFAILURE) == 0 && 1049 (messagep->status & S_MESSAGE_PERMFAILURE) == 0) { 1050 log_info("%s: to=<%s@%s>, delay=%d, stat=Sent", 1051 messagep->message_uid, 1052 messagep->recipient.user, 1053 messagep->recipient.domain, 1054 time(NULL) - messagep->creation); 1055 } 1056 1057 imsg_compose(env->sc_ibufs[PROC_QUEUE], 1058 IMSG_QUEUE_MESSAGE_UPDATE, 0, 0, -1, messagep, 1059 sizeof(struct message)); 1060 TAILQ_REMOVE(&batchp->messages, messagep, entry); 1061 free(messagep); 1062 } 1063 1064 SPLAY_REMOVE(batchtree, &env->batch_queue, batchp); 1065 1066 if (batchp->messagefp) 1067 fclose(batchp->messagefp); 1068 1069 free(batchp); 1070 1071 } 1072