1 /* 2 * Copyright (c) 1983 Eric P. Allman 3 * Copyright (c) 1988 Regents of the University of California. 4 * All rights reserved. 5 * 6 * %sccs.include.redist.c% 7 */ 8 9 # include "sendmail.h" 10 11 #ifndef lint 12 #ifdef SMTP 13 static char sccsid[] = "@(#)usersmtp.c 6.31 (Berkeley) 05/21/93 (with SMTP)"; 14 #else 15 static char sccsid[] = "@(#)usersmtp.c 6.31 (Berkeley) 05/21/93 (without SMTP)"; 16 #endif 17 #endif /* not lint */ 18 19 # include <sysexits.h> 20 # include <errno.h> 21 22 # ifdef SMTP 23 24 /* 25 ** USERSMTP -- run SMTP protocol from the user end. 26 ** 27 ** This protocol is described in RFC821. 28 */ 29 30 #define REPLYTYPE(r) ((r) / 100) /* first digit of reply code */ 31 #define REPLYCLASS(r) (((r) / 10) % 10) /* second digit of reply code */ 32 #define SMTPCLOSING 421 /* "Service Shutting Down" */ 33 34 char SmtpMsgBuffer[MAXLINE]; /* buffer for commands */ 35 char SmtpReplyBuffer[MAXLINE]; /* buffer for replies */ 36 char SmtpError[MAXLINE] = ""; /* save failure error messages */ 37 int SmtpPid; /* pid of mailer */ 38 39 #ifdef __STDC__ 40 extern smtpmessage(char *f, MAILER *m, MCI *mci, ...); 41 #endif 42 /* 43 ** SMTPINIT -- initialize SMTP. 44 ** 45 ** Opens the connection and sends the initial protocol. 46 ** 47 ** Parameters: 48 ** m -- mailer to create connection to. 49 ** pvp -- pointer to parameter vector to pass to 50 ** the mailer. 51 ** 52 ** Returns: 53 ** none. 54 ** 55 ** Side Effects: 56 ** creates connection and sends initial protocol. 57 */ 58 59 smtpinit(m, mci, e) 60 struct mailer *m; 61 register MCI *mci; 62 ENVELOPE *e; 63 { 64 register int r; 65 register char *p; 66 extern STAB *stab(); 67 extern void esmtp_check(); 68 extern void helo_options(); 69 70 if (tTd(17, 1)) 71 { 72 printf("smtpinit "); 73 mci_dump(mci); 74 } 75 76 /* 77 ** Open the connection to the mailer. 78 */ 79 80 SmtpError[0] = '\0'; 81 CurHostName = mci->mci_host; /* XXX UGLY XXX */ 82 switch (mci->mci_state) 83 { 84 case MCIS_ACTIVE: 85 /* need to clear old information */ 86 smtprset(m, mci, e); 87 /* fall through */ 88 89 case MCIS_OPEN: 90 return; 91 92 case MCIS_ERROR: 93 case MCIS_SSD: 94 /* shouldn't happen */ 95 smtpquit(m, mci, e); 96 /* fall through */ 97 98 case MCIS_CLOSED: 99 syserr("451 smtpinit: state CLOSED"); 100 return; 101 102 case MCIS_OPENING: 103 break; 104 } 105 106 mci->mci_state = MCIS_OPENING; 107 108 /* 109 ** Get the greeting message. 110 ** This should appear spontaneously. Give it five minutes to 111 ** happen. 112 */ 113 114 SmtpPhase = mci->mci_phase = "greeting wait"; 115 setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); 116 r = reply(m, mci, e, TimeOuts.to_initial, esmtp_check); 117 if (r < 0 || REPLYTYPE(r) != 2) 118 goto tempfail1; 119 120 /* 121 ** Send the HELO command. 122 ** My mother taught me to always introduce myself. 123 */ 124 125 if (bitnset(M_ESMTP, m->m_flags)) 126 mci->mci_flags |= MCIF_ESMTP; 127 128 tryhelo: 129 if (bitset(MCIF_ESMTP, mci->mci_flags)) 130 { 131 smtpmessage("EHLO %s", m, mci, MyHostName); 132 SmtpPhase = mci->mci_phase = "EHLO wait"; 133 } 134 else 135 { 136 smtpmessage("HELO %s", m, mci, MyHostName); 137 SmtpPhase = mci->mci_phase = "HELO wait"; 138 } 139 setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); 140 r = reply(m, mci, e, TimeOuts.to_helo, helo_options); 141 if (r < 0) 142 goto tempfail1; 143 else if (REPLYTYPE(r) == 5) 144 { 145 if (bitset(MCIF_ESMTP, mci->mci_flags)) 146 { 147 /* try old SMTP instead */ 148 mci->mci_flags &= ~MCIF_ESMTP; 149 goto tryhelo; 150 } 151 goto unavailable; 152 } 153 else if (REPLYTYPE(r) != 2) 154 goto tempfail1; 155 156 /* 157 ** Check to see if we actually ended up talking to ourself. 158 ** This means we didn't know about an alias or MX, or we managed 159 ** to connect to an echo server. 160 */ 161 162 p = strchr(&SmtpReplyBuffer[4], ' '); 163 if (p != NULL) 164 *p == '\0'; 165 if (strcasecmp(&SmtpReplyBuffer[4], MyHostName) == 0) 166 { 167 syserr("553 %s config error: mail loops back to myself", 168 MyHostName); 169 mci->mci_exitstat = EX_CONFIG; 170 mci->mci_errno = 0; 171 smtpquit(m, mci, e); 172 return; 173 } 174 175 /* 176 ** If this is expected to be another sendmail, send some internal 177 ** commands. 178 */ 179 180 if (bitnset(M_INTERNAL, m->m_flags)) 181 { 182 /* tell it to be verbose */ 183 smtpmessage("VERB", m, mci); 184 r = reply(m, mci, e, TimeOuts.to_miscshort, NULL); 185 if (r < 0) 186 goto tempfail2; 187 } 188 189 mci->mci_state = MCIS_OPEN; 190 return; 191 192 tempfail1: 193 tempfail2: 194 mci->mci_exitstat = EX_TEMPFAIL; 195 if (mci->mci_errno == 0) 196 mci->mci_errno = errno; 197 if (mci->mci_state != MCIS_CLOSED) 198 smtpquit(m, mci, e); 199 return; 200 201 unavailable: 202 mci->mci_exitstat = EX_UNAVAILABLE; 203 mci->mci_errno = errno; 204 smtpquit(m, mci, e); 205 return; 206 } 207 /* 208 ** ESMTP_CHECK -- check to see if this implementation likes ESMTP protocol 209 ** 210 ** 211 ** Parameters: 212 ** line -- the response line. 213 ** m -- the mailer. 214 ** mci -- the mailer connection info. 215 ** e -- the envelope. 216 ** 217 ** Returns: 218 ** none. 219 */ 220 221 void 222 esmtp_check(line, m, mci, e) 223 char *line; 224 MAILER *m; 225 register MCI *mci; 226 ENVELOPE *e; 227 { 228 if (strlen(line) < 5) 229 return; 230 line += 4; 231 if (strncmp(line, "ESMTP ", 6) == 0) 232 mci->mci_flags |= MCIF_ESMTP; 233 } 234 /* 235 ** HELO_OPTIONS -- process the options on a HELO line. 236 ** 237 ** Parameters: 238 ** line -- the response line. 239 ** m -- the mailer. 240 ** mci -- the mailer connection info. 241 ** e -- the envelope. 242 ** 243 ** Returns: 244 ** none. 245 */ 246 247 void 248 helo_options(line, m, mci, e) 249 char *line; 250 MAILER *m; 251 register MCI *mci; 252 ENVELOPE *e; 253 { 254 register char *p; 255 256 if (strlen(line) < 5) 257 return; 258 line += 4; 259 p = strchr(line, ' '); 260 if (p != NULL) 261 *p++ = '\0'; 262 if (strcasecmp(line, "size") == 0) 263 { 264 mci->mci_flags |= MCIF_SIZE; 265 if (p != NULL) 266 mci->mci_maxsize = atol(p); 267 } 268 else if (strcasecmp(line, "8bitmime") == 0) 269 mci->mci_flags |= MCIF_8BITMIME; 270 else if (strcasecmp(line, "expn") == 0) 271 mci->mci_flags |= MCIF_EXPN; 272 } 273 /* 274 ** SMTPMAILFROM -- send MAIL command 275 ** 276 ** Parameters: 277 ** m -- the mailer. 278 ** mci -- the mailer connection structure. 279 ** e -- the envelope (including the sender to specify). 280 */ 281 282 smtpmailfrom(m, mci, e) 283 struct mailer *m; 284 MCI *mci; 285 ENVELOPE *e; 286 { 287 int r; 288 char buf[MAXNAME]; 289 char optbuf[MAXLINE]; 290 291 if (tTd(17, 2)) 292 printf("smtpmailfrom: CurHost=%s\n", CurHostName); 293 294 /* set up appropriate options to include */ 295 if (bitset(MCIF_SIZE, mci->mci_flags)) 296 sprintf(optbuf, " SIZE=%ld", e->e_msgsize); 297 else 298 strcpy(optbuf, ""); 299 300 /* 301 ** Send the MAIL command. 302 ** Designates the sender. 303 */ 304 305 mci->mci_state = MCIS_ACTIVE; 306 307 if (bitset(EF_RESPONSE, e->e_flags) && 308 !bitnset(M_NO_NULL_FROM, m->m_flags)) 309 (void) strcpy(buf, ""); 310 else 311 expand("\201g", buf, &buf[sizeof buf - 1], e); 312 if (e->e_from.q_mailer == LocalMailer || 313 !bitnset(M_FROMPATH, m->m_flags)) 314 { 315 smtpmessage("MAIL From:<%s>%s", m, mci, buf, optbuf); 316 } 317 else 318 { 319 smtpmessage("MAIL From:<@%s%c%s>%s", m, mci, MyHostName, 320 buf[0] == '@' ? ',' : ':', buf, optbuf); 321 } 322 SmtpPhase = mci->mci_phase = "MAIL wait"; 323 setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); 324 r = reply(m, mci, e, TimeOuts.to_mail, NULL); 325 if (r < 0 || REPLYTYPE(r) == 4) 326 { 327 mci->mci_exitstat = EX_TEMPFAIL; 328 mci->mci_errno = errno; 329 smtpquit(m, mci, e); 330 return EX_TEMPFAIL; 331 } 332 else if (r == 250) 333 { 334 mci->mci_exitstat = EX_OK; 335 return EX_OK; 336 } 337 else if (r == 552) 338 { 339 /* signal service unavailable */ 340 mci->mci_exitstat = EX_UNAVAILABLE; 341 smtpquit(m, mci, e); 342 return EX_UNAVAILABLE; 343 } 344 345 #ifdef LOG 346 if (LogLevel > 1) 347 { 348 syslog(LOG_CRIT, "%s: SMTP MAIL protocol error: %s", 349 e->e_id, SmtpReplyBuffer); 350 } 351 #endif 352 353 /* protocol error -- close up */ 354 smtpquit(m, mci, e); 355 mci->mci_exitstat = EX_PROTOCOL; 356 return EX_PROTOCOL; 357 } 358 /* 359 ** SMTPRCPT -- designate recipient. 360 ** 361 ** Parameters: 362 ** to -- address of recipient. 363 ** m -- the mailer we are sending to. 364 ** mci -- the connection info for this transaction. 365 ** e -- the envelope for this transaction. 366 ** 367 ** Returns: 368 ** exit status corresponding to recipient status. 369 ** 370 ** Side Effects: 371 ** Sends the mail via SMTP. 372 */ 373 374 smtprcpt(to, m, mci, e) 375 ADDRESS *to; 376 register MAILER *m; 377 MCI *mci; 378 ENVELOPE *e; 379 { 380 register int r; 381 382 smtpmessage("RCPT To:<%s>", m, mci, to->q_user); 383 384 SmtpPhase = mci->mci_phase = "RCPT wait"; 385 setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); 386 r = reply(m, mci, e, TimeOuts.to_rcpt, NULL); 387 if (r < 0 || REPLYTYPE(r) == 4) 388 return (EX_TEMPFAIL); 389 else if (REPLYTYPE(r) == 2) 390 return (EX_OK); 391 else if (r == 550 || r == 551 || r == 553) 392 return (EX_NOUSER); 393 else if (r == 552 || r == 554) 394 return (EX_UNAVAILABLE); 395 396 #ifdef LOG 397 if (LogLevel > 1) 398 { 399 syslog(LOG_CRIT, "%s: SMTP RCPT protocol error: %s", 400 e->e_id, SmtpReplyBuffer); 401 } 402 #endif 403 404 return (EX_PROTOCOL); 405 } 406 /* 407 ** SMTPDATA -- send the data and clean up the transaction. 408 ** 409 ** Parameters: 410 ** m -- mailer being sent to. 411 ** e -- the envelope for this message. 412 ** 413 ** Returns: 414 ** exit status corresponding to DATA command. 415 ** 416 ** Side Effects: 417 ** none. 418 */ 419 420 smtpdata(m, mci, e) 421 struct mailer *m; 422 register MCI *mci; 423 register ENVELOPE *e; 424 { 425 register int r; 426 427 /* 428 ** Send the data. 429 ** First send the command and check that it is ok. 430 ** Then send the data. 431 ** Follow it up with a dot to terminate. 432 ** Finally get the results of the transaction. 433 */ 434 435 /* send the command and check ok to proceed */ 436 smtpmessage("DATA", m, mci); 437 SmtpPhase = mci->mci_phase = "DATA wait"; 438 setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); 439 r = reply(m, mci, e, TimeOuts.to_datainit, NULL); 440 if (r < 0 || REPLYTYPE(r) == 4) 441 { 442 smtpquit(m, mci, e); 443 return (EX_TEMPFAIL); 444 } 445 else if (r == 554) 446 { 447 smtprset(m, mci, e); 448 return (EX_UNAVAILABLE); 449 } 450 else if (r != 354) 451 { 452 #ifdef LOG 453 if (LogLevel > 1) 454 { 455 syslog(LOG_CRIT, "%s: SMTP DATA-1 protocol error: %s", 456 e->e_id, SmtpReplyBuffer); 457 } 458 #endif 459 smtprset(m, mci, e); 460 return (EX_PROTOCOL); 461 } 462 463 /* now output the actual message */ 464 (*e->e_puthdr)(mci->mci_out, m, e); 465 putline("\n", mci->mci_out, m); 466 (*e->e_putbody)(mci->mci_out, m, e, NULL); 467 468 /* terminate the message */ 469 fprintf(mci->mci_out, ".%s", m->m_eol); 470 if (Verbose) 471 nmessage(">>> ."); 472 473 /* check for the results of the transaction */ 474 SmtpPhase = mci->mci_phase = "result wait"; 475 setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); 476 r = reply(m, mci, e, TimeOuts.to_datafinal, NULL); 477 if (r < 0) 478 { 479 smtpquit(m, mci, e); 480 return (EX_TEMPFAIL); 481 } 482 mci->mci_state = MCIS_OPEN; 483 e->e_statmsg = newstr(&SmtpReplyBuffer[4]); 484 if (REPLYTYPE(r) == 4) 485 return (EX_TEMPFAIL); 486 else if (r == 250) 487 return (EX_OK); 488 else if (r == 552 || r == 554) 489 return (EX_UNAVAILABLE); 490 #ifdef LOG 491 if (LogLevel > 1) 492 { 493 syslog(LOG_CRIT, "%s: SMTP DATA-2 protocol error: %s", 494 e->e_id, SmtpReplyBuffer); 495 } 496 #endif 497 return (EX_PROTOCOL); 498 } 499 /* 500 ** SMTPQUIT -- close the SMTP connection. 501 ** 502 ** Parameters: 503 ** m -- a pointer to the mailer. 504 ** 505 ** Returns: 506 ** none. 507 ** 508 ** Side Effects: 509 ** sends the final protocol and closes the connection. 510 */ 511 512 smtpquit(m, mci, e) 513 register MAILER *m; 514 register MCI *mci; 515 ENVELOPE *e; 516 { 517 int i; 518 519 /* send the quit message if we haven't gotten I/O error */ 520 if (mci->mci_state != MCIS_ERROR) 521 { 522 smtpmessage("QUIT", m, mci); 523 (void) reply(m, mci, e, TimeOuts.to_quit, NULL); 524 if (mci->mci_state == MCIS_CLOSED) 525 return; 526 } 527 528 /* now actually close the connection and pick up the zombie */ 529 i = endmailer(mci, e, m->m_argv); 530 if (i != EX_OK) 531 syserr("451 smtpquit %s: stat %d", m->m_argv[0], i); 532 } 533 /* 534 ** SMTPRSET -- send a RSET (reset) command 535 */ 536 537 smtprset(m, mci, e) 538 register MAILER *m; 539 register MCI *mci; 540 ENVELOPE *e; 541 { 542 int r; 543 544 smtpmessage("RSET", m, mci); 545 r = reply(m, mci, e, TimeOuts.to_rset, NULL); 546 if (r < 0) 547 mci->mci_state = MCIS_ERROR; 548 else if (REPLYTYPE(r) == 2) 549 { 550 mci->mci_state = MCIS_OPEN; 551 return; 552 } 553 smtpquit(m, mci, e); 554 } 555 /* 556 ** SMTPPROBE -- check the connection state 557 */ 558 559 smtpprobe(mci) 560 register MCI *mci; 561 { 562 int r; 563 MAILER *m = mci->mci_mailer; 564 extern ENVELOPE BlankEnvelope; 565 ENVELOPE *e = &BlankEnvelope; 566 567 smtpmessage("RSET", m, mci); 568 r = reply(m, mci, e, TimeOuts.to_miscshort, NULL); 569 if (r < 0 || REPLYTYPE(r) != 2) 570 smtpquit(m, mci, e); 571 return r; 572 } 573 /* 574 ** REPLY -- read arpanet reply 575 ** 576 ** Parameters: 577 ** m -- the mailer we are reading the reply from. 578 ** mci -- the mailer connection info structure. 579 ** e -- the current envelope. 580 ** timeout -- the timeout for reads. 581 ** pfunc -- processing function for second and subsequent 582 ** lines of response -- if null, no special 583 ** processing is done. 584 ** 585 ** Returns: 586 ** reply code it reads. 587 ** 588 ** Side Effects: 589 ** flushes the mail file. 590 */ 591 592 reply(m, mci, e, timeout, pfunc) 593 MAILER *m; 594 MCI *mci; 595 ENVELOPE *e; 596 time_t timeout; 597 void (*pfunc)(); 598 { 599 register char *bufp; 600 register int r; 601 bool firstline = TRUE; 602 char junkbuf[MAXLINE]; 603 604 if (mci->mci_out != NULL) 605 (void) fflush(mci->mci_out); 606 607 if (tTd(18, 1)) 608 printf("reply\n"); 609 610 /* 611 ** Read the input line, being careful not to hang. 612 */ 613 614 for (bufp = SmtpReplyBuffer;; bufp = junkbuf) 615 { 616 register char *p; 617 extern time_t curtime(); 618 619 /* actually do the read */ 620 if (e->e_xfp != NULL) 621 (void) fflush(e->e_xfp); /* for debugging */ 622 623 /* if we are in the process of closing just give the code */ 624 if (mci->mci_state == MCIS_CLOSED) 625 return (SMTPCLOSING); 626 627 if (mci->mci_out != NULL) 628 fflush(mci->mci_out); 629 630 /* get the line from the other side */ 631 p = sfgets(bufp, MAXLINE, mci->mci_in, timeout); 632 mci->mci_lastuse = curtime(); 633 634 if (p == NULL) 635 { 636 extern char MsgBuf[]; /* err.c */ 637 638 /* if the remote end closed early, fake an error */ 639 if (errno == 0) 640 # ifdef ECONNRESET 641 errno = ECONNRESET; 642 # else /* ECONNRESET */ 643 errno = EPIPE; 644 # endif /* ECONNRESET */ 645 646 mci->mci_errno = errno; 647 mci->mci_exitstat = EX_TEMPFAIL; 648 message("451 %s: reply: read error from %s", 649 e->e_id == NULL ? "NOQUEUE" : e->e_id, 650 mci->mci_host); 651 /* if debugging, pause so we can see state */ 652 if (tTd(18, 100)) 653 pause(); 654 # ifdef LOG 655 if (LogLevel > 1) 656 syslog(LOG_INFO, "%s", &MsgBuf[4]); 657 # endif /* LOG */ 658 mci->mci_state = MCIS_ERROR; 659 smtpquit(m, mci, e); 660 return (-1); 661 } 662 fixcrlf(bufp, TRUE); 663 664 if (e->e_xfp != NULL && strchr("45", bufp[0]) != NULL) 665 { 666 /* serious error -- log the previous command */ 667 if (SmtpMsgBuffer[0] != '\0') 668 fprintf(e->e_xfp, ">>> %s\n", SmtpMsgBuffer); 669 SmtpMsgBuffer[0] = '\0'; 670 671 /* now log the message as from the other side */ 672 fprintf(e->e_xfp, "<<< %s\n", bufp); 673 } 674 675 /* display the input for verbose mode */ 676 if (Verbose) 677 nmessage("050 %s", bufp); 678 679 /* process the line */ 680 if (pfunc != NULL && !firstline) 681 (*pfunc)(bufp, m, mci, e); 682 683 firstline = FALSE; 684 685 /* if continuation is required, we can go on */ 686 if (bufp[3] == '-') 687 continue; 688 689 /* ignore improperly formated input */ 690 if (!(isascii(bufp[0]) && isdigit(bufp[0]))) 691 continue; 692 693 /* decode the reply code */ 694 r = atoi(bufp); 695 696 /* extra semantics: 0xx codes are "informational" */ 697 if (r >= 100) 698 break; 699 } 700 701 /* 702 ** Now look at SmtpReplyBuffer -- only care about the first 703 ** line of the response from here on out. 704 */ 705 706 /* save temporary failure messages for posterity */ 707 if (SmtpReplyBuffer[0] == '4' && SmtpError[0] == '\0') 708 (void) strcpy(SmtpError, SmtpReplyBuffer); 709 710 /* reply code 421 is "Service Shutting Down" */ 711 if (r == SMTPCLOSING && mci->mci_state != MCIS_SSD) 712 { 713 /* send the quit protocol */ 714 mci->mci_state = MCIS_SSD; 715 smtpquit(m, mci, e); 716 } 717 718 return (r); 719 } 720 /* 721 ** SMTPMESSAGE -- send message to server 722 ** 723 ** Parameters: 724 ** f -- format 725 ** m -- the mailer to control formatting. 726 ** a, b, c -- parameters 727 ** 728 ** Returns: 729 ** none. 730 ** 731 ** Side Effects: 732 ** writes message to mci->mci_out. 733 */ 734 735 /*VARARGS1*/ 736 #ifdef __STDC__ 737 smtpmessage(char *f, MAILER *m, MCI *mci, ...) 738 #else 739 smtpmessage(f, m, mci, va_alist) 740 char *f; 741 MAILER *m; 742 MCI *mci; 743 va_dcl 744 #endif 745 { 746 VA_LOCAL_DECL 747 748 VA_START(mci); 749 (void) vsprintf(SmtpMsgBuffer, f, ap); 750 VA_END; 751 752 if (tTd(18, 1) || Verbose) 753 nmessage(">>> %s", SmtpMsgBuffer); 754 if (mci->mci_out != NULL) 755 { 756 fprintf(mci->mci_out, "%s%s", SmtpMsgBuffer, 757 m == NULL ? "\r\n" : m->m_eol); 758 } 759 else if (tTd(18, 1)) 760 { 761 printf("smtpmessage: NULL mci_out\n"); 762 } 763 } 764 765 # endif /* SMTP */ 766