usersmtp.c (147078) | usersmtp.c (157001) |
---|---|
1/* | 1/* |
2 * Copyright (c) 1998-2005 Sendmail, Inc. and its suppliers. | 2 * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers. |
3 * All rights reserved. 4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 5 * Copyright (c) 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * By using this file, you agree to the terms and conditions set 9 * forth in the LICENSE file which can be found at the top level of 10 * the sendmail distribution. 11 * 12 */ 13 14#include <sendmail.h> 15 | 3 * All rights reserved. 4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 5 * Copyright (c) 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * By using this file, you agree to the terms and conditions set 9 * forth in the LICENSE file which can be found at the top level of 10 * the sendmail distribution. 11 * 12 */ 13 14#include <sendmail.h> 15 |
16SM_RCSID("@(#)$Id: usersmtp.c,v 8.463 2005/03/16 00:36:09 ca Exp $") | 16SM_RCSID("@(#)$Id: usersmtp.c,v 8.467 2006/03/19 06:07:56 ca Exp $") |
17 18#include <sysexits.h> 19 20 | 17 18#include <sysexits.h> 19 20 |
21static void datatimeout __P((int)); | |
22static void esmtp_check __P((char *, bool, MAILER *, MCI *, ENVELOPE *)); 23static void helo_options __P((char *, bool, MAILER *, MCI *, ENVELOPE *)); 24static int smtprcptstat __P((ADDRESS *, MAILER *, MCI *, ENVELOPE *)); 25 26#if SASL 27extern void *sm_sasl_malloc __P((unsigned long)); 28extern void sm_sasl_free __P((void *)); 29#endif /* SASL */ 30 31/* 32** USERSMTP -- run SMTP protocol from the user end. 33** 34** This protocol is described in RFC821. 35*/ 36 | 21static void esmtp_check __P((char *, bool, MAILER *, MCI *, ENVELOPE *)); 22static void helo_options __P((char *, bool, MAILER *, MCI *, ENVELOPE *)); 23static int smtprcptstat __P((ADDRESS *, MAILER *, MCI *, ENVELOPE *)); 24 25#if SASL 26extern void *sm_sasl_malloc __P((unsigned long)); 27extern void sm_sasl_free __P((void *)); 28#endif /* SASL */ 29 30/* 31** USERSMTP -- run SMTP protocol from the user end. 32** 33** This protocol is described in RFC821. 34*/ 35 |
37#define REPLYTYPE(r) ((r) / 100) /* first digit of reply code */ | |
38#define REPLYCLASS(r) (((r) / 10) % 10) /* second digit of reply code */ 39#define SMTPCLOSING 421 /* "Service Shutting Down" */ 40 41#define ENHSCN(e, d) ((e) == NULL ? (d) : (e)) 42 43#define ENHSCN_RPOOL(e, d, rpool) \ 44 ((e) == NULL ? (d) : sm_rpool_strdup_x(rpool, e)) 45 --- 2440 unchanged lines hidden (view full) --- 2486** m -- mailer being sent to. 2487** mci -- the mailer connection information. 2488** e -- the envelope for this message. 2489** 2490** Returns: 2491** exit status corresponding to DATA command. 2492*/ 2493 | 36#define REPLYCLASS(r) (((r) / 10) % 10) /* second digit of reply code */ 37#define SMTPCLOSING 421 /* "Service Shutting Down" */ 38 39#define ENHSCN(e, d) ((e) == NULL ? (d) : (e)) 40 41#define ENHSCN_RPOOL(e, d, rpool) \ 42 ((e) == NULL ? (d) : sm_rpool_strdup_x(rpool, e)) 43 --- 2440 unchanged lines hidden (view full) --- 2484** m -- mailer being sent to. 2485** mci -- the mailer connection information. 2486** e -- the envelope for this message. 2487** 2488** Returns: 2489** exit status corresponding to DATA command. 2490*/ 2491 |
2494static jmp_buf CtxDataTimeout; 2495static SM_EVENT *volatile DataTimeout = NULL; 2496 | |
2497int 2498smtpdata(m, mci, e, ctladdr, xstart) 2499 MAILER *m; 2500 register MCI *mci; 2501 register ENVELOPE *e; 2502 ADDRESS *ctladdr; 2503 time_t xstart; 2504{ 2505 register int r; 2506 int rstat; 2507 int xstat; | 2492int 2493smtpdata(m, mci, e, ctladdr, xstart) 2494 MAILER *m; 2495 register MCI *mci; 2496 register ENVELOPE *e; 2497 ADDRESS *ctladdr; 2498 time_t xstart; 2499{ 2500 register int r; 2501 int rstat; 2502 int xstat; |
2508 time_t timeout; | 2503 int timeout; |
2509 char *enhsc; 2510 2511 /* 2512 ** Check if connection is gone, if so 2513 ** it's a tempfail and we use mci_errno 2514 ** for the reason. 2515 */ 2516 --- 107 unchanged lines hidden (view full) --- 2624#endif /* PIPELINING */ 2625 2626 /* 2627 ** Set timeout around data writes. Make it at least large 2628 ** enough for DNS timeouts on all recipients plus some fudge 2629 ** factor. The main thing is that it should not be infinite. 2630 */ 2631 | 2504 char *enhsc; 2505 2506 /* 2507 ** Check if connection is gone, if so 2508 ** it's a tempfail and we use mci_errno 2509 ** for the reason. 2510 */ 2511 --- 107 unchanged lines hidden (view full) --- 2619#endif /* PIPELINING */ 2620 2621 /* 2622 ** Set timeout around data writes. Make it at least large 2623 ** enough for DNS timeouts on all recipients plus some fudge 2624 ** factor. The main thing is that it should not be infinite. 2625 */ 2626 |
2632 if (setjmp(CtxDataTimeout) != 0) 2633 { 2634 mci->mci_errno = errno; 2635 mci->mci_state = MCIS_ERROR; 2636 mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL); 2637 2638 /* 2639 ** If putbody() couldn't finish due to a timeout, 2640 ** rewind it here in the timeout handler. See 2641 ** comments at the end of putbody() for reasoning. 2642 */ 2643 2644 if (e->e_dfp != NULL) 2645 (void) bfrewind(e->e_dfp); 2646 2647 errno = mci->mci_errno; 2648 syserr("451 4.4.1 timeout writing message to %s", CurHostName); 2649 smtpquit(m, mci, e); 2650 return EX_TEMPFAIL; 2651 } 2652 | |
2653 if (tTd(18, 101)) 2654 { 2655 /* simulate a DATA timeout */ | 2627 if (tTd(18, 101)) 2628 { 2629 /* simulate a DATA timeout */ |
2656 timeout = 1; | 2630 timeout = 10; |
2657 } 2658 else | 2631 } 2632 else |
2659 timeout = DATA_PROGRESS_TIMEOUT; | 2633 timeout = DATA_PROGRESS_TIMEOUT * 1000; 2634 sm_io_setinfo(mci->mci_out, SM_IO_WHAT_TIMEOUT, &timeout); |
2660 | 2635 |
2661 DataTimeout = sm_setevent(timeout, datatimeout, 0); | |
2662 | 2636 |
2663 | |
2664 /* 2665 ** Output the actual message. 2666 */ 2667 | 2637 /* 2638 ** Output the actual message. 2639 */ 2640 |
2668 (*e->e_puthdr)(mci, e->e_header, e, M87F_OUTER); | 2641 if (!(*e->e_puthdr)(mci, e->e_header, e, M87F_OUTER)) 2642 goto writeerr; |
2669 2670 if (tTd(18, 101)) 2671 { 2672 /* simulate a DATA timeout */ 2673 (void) sleep(2); 2674 } 2675 | 2643 2644 if (tTd(18, 101)) 2645 { 2646 /* simulate a DATA timeout */ 2647 (void) sleep(2); 2648 } 2649 |
2676 (*e->e_putbody)(mci, e, NULL); | 2650 if (!(*e->e_putbody)(mci, e, NULL)) 2651 goto writeerr; |
2677 2678 /* 2679 ** Cleanup after sending message. 2680 */ 2681 | 2652 2653 /* 2654 ** Cleanup after sending message. 2655 */ 2656 |
2682 if (DataTimeout != NULL) 2683 sm_clrevent(DataTimeout); | |
2684 2685#if PIPELINING 2686 } 2687#endif /* PIPELINING */ 2688 2689#if _FFR_CATCH_BROKEN_MTAS 2690 if (sm_io_getinfo(mci->mci_in, SM_IO_IS_READABLE, NULL) > 0) 2691 { --- 23 unchanged lines hidden (view full) --- 2715 mci->mci_errno = EIO; 2716 mci->mci_state = MCIS_ERROR; 2717 mci_setstat(mci, EX_IOERR, "4.4.2", NULL); 2718 smtpquit(m, mci, e); 2719 return EX_IOERR; 2720 } 2721 2722 /* terminate the message */ | 2657 2658#if PIPELINING 2659 } 2660#endif /* PIPELINING */ 2661 2662#if _FFR_CATCH_BROKEN_MTAS 2663 if (sm_io_getinfo(mci->mci_in, SM_IO_IS_READABLE, NULL) > 0) 2664 { --- 23 unchanged lines hidden (view full) --- 2688 mci->mci_errno = EIO; 2689 mci->mci_state = MCIS_ERROR; 2690 mci_setstat(mci, EX_IOERR, "4.4.2", NULL); 2691 smtpquit(m, mci, e); 2692 return EX_IOERR; 2693 } 2694 2695 /* terminate the message */ |
2723 (void) sm_io_fprintf(mci->mci_out, SM_TIME_DEFAULT, ".%s", m->m_eol); | 2696 if (sm_io_fprintf(mci->mci_out, SM_TIME_DEFAULT, ".%s", m->m_eol) == 2697 SM_IO_EOF) 2698 goto writeerr; |
2724 if (TrafficLogFile != NULL) 2725 (void) sm_io_fprintf(TrafficLogFile, SM_TIME_DEFAULT, 2726 "%05d >>> .\n", (int) CurrentPid); 2727 if (Verbose) 2728 nmessage(">>> ."); 2729 2730 /* check for the results of the transaction */ 2731 SmtpPhase = mci->mci_phase = "client DATA status"; --- 34 unchanged lines hidden (view full) --- 2766 if (LogLevel > 1) 2767 { 2768 sm_syslog(LOG_CRIT, e->e_id, 2769 "%.100s: SMTP DATA-2 protocol error: %s", 2770 CurHostName, 2771 shortenstring(SmtpReplyBuffer, 403)); 2772 } 2773 return rstat; | 2699 if (TrafficLogFile != NULL) 2700 (void) sm_io_fprintf(TrafficLogFile, SM_TIME_DEFAULT, 2701 "%05d >>> .\n", (int) CurrentPid); 2702 if (Verbose) 2703 nmessage(">>> ."); 2704 2705 /* check for the results of the transaction */ 2706 SmtpPhase = mci->mci_phase = "client DATA status"; --- 34 unchanged lines hidden (view full) --- 2741 if (LogLevel > 1) 2742 { 2743 sm_syslog(LOG_CRIT, e->e_id, 2744 "%.100s: SMTP DATA-2 protocol error: %s", 2745 CurHostName, 2746 shortenstring(SmtpReplyBuffer, 403)); 2747 } 2748 return rstat; |
2774} | |
2775 | 2749 |
2776static void 2777datatimeout(ignore) 2778 int ignore; 2779{ 2780 int save_errno = errno; | 2750 writeerr: 2751 mci->mci_errno = errno; 2752 mci->mci_state = MCIS_ERROR; 2753 mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL); |
2781 2782 /* | 2754 2755 /* |
2783 ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD 2784 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE 2785 ** DOING. | 2756 ** If putbody() couldn't finish due to a timeout, 2757 ** rewind it here in the timeout handler. See 2758 ** comments at the end of putbody() for reasoning. |
2786 */ 2787 | 2759 */ 2760 |
2788 if (DataProgress) 2789 { 2790 time_t timeout; | 2761 if (e->e_dfp != NULL) 2762 (void) bfrewind(e->e_dfp); |
2791 | 2763 |
2792 /* check back again later */ 2793 if (tTd(18, 101)) 2794 { 2795 /* simulate a DATA timeout */ 2796 timeout = 1; 2797 } 2798 else 2799 timeout = DATA_PROGRESS_TIMEOUT; 2800 2801 /* reset the timeout */ 2802 DataTimeout = sm_sigsafe_setevent(timeout, datatimeout, 0); 2803 DataProgress = false; 2804 } 2805 else 2806 { 2807 /* event is done */ 2808 DataTimeout = NULL; 2809 } 2810 2811 /* if no progress was made or problem resetting event, die now */ 2812 if (DataTimeout == NULL) 2813 { 2814 errno = ETIMEDOUT; 2815 longjmp(CtxDataTimeout, 1); 2816 } 2817 errno = save_errno; | 2764 errno = mci->mci_errno; 2765 syserr("451 4.4.1 timeout writing message to %s", CurHostName); 2766 smtpquit(m, mci, e); 2767 return EX_TEMPFAIL; |
2818} | 2768} |
2769 |
|
2819/* 2820** SMTPGETSTAT -- get status code from DATA in LMTP 2821** 2822** Parameters: 2823** m -- the mailer to which we are sending the message. 2824** mci -- the mailer connection structure. 2825** e -- the current envelope. 2826** --- 189 unchanged lines hidden (view full) --- 3016 ** However, if 421 is returned for the RSET, leave 3017 ** mci_state alone (MCIS_SSD can be set in reply() 3018 ** and MCIS_CLOSED can be set in smtpquit() if 3019 ** reply() gets a 421 and calls smtpquit()). 3020 */ 3021 3022 if (mci->mci_state != MCIS_SSD && mci->mci_state != MCIS_CLOSED) 3023 mci->mci_state = MCIS_OPEN; | 2770/* 2771** SMTPGETSTAT -- get status code from DATA in LMTP 2772** 2773** Parameters: 2774** m -- the mailer to which we are sending the message. 2775** mci -- the mailer connection structure. 2776** e -- the current envelope. 2777** --- 189 unchanged lines hidden (view full) --- 2967 ** However, if 421 is returned for the RSET, leave 2968 ** mci_state alone (MCIS_SSD can be set in reply() 2969 ** and MCIS_CLOSED can be set in smtpquit() if 2970 ** reply() gets a 421 and calls smtpquit()). 2971 */ 2972 2973 if (mci->mci_state != MCIS_SSD && mci->mci_state != MCIS_CLOSED) 2974 mci->mci_state = MCIS_OPEN; |
2975 else if (mci->mci_exitstat == EX_OK) 2976 mci_setstat(mci, EX_TEMPFAIL, "4.5.0", NULL); |
|
3024} 3025/* 3026** SMTPPROBE -- check the connection state 3027** 3028** Parameters: 3029** mci -- the mailer connection information. 3030** 3031** Returns: --- 323 unchanged lines hidden --- | 2977} 2978/* 2979** SMTPPROBE -- check the connection state 2980** 2981** Parameters: 2982** mci -- the mailer connection information. 2983** 2984** Returns: --- 323 unchanged lines hidden --- |