Deleted Added
full compact
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 ---