Re: [Exim] Error log - TLS auth

Top Page
Delete this message
Reply to this message
Author: Philip Hazel
Date:  
To: Karl Schmidt
CC: exim-users
Subject: Re: [Exim] Error log - TLS auth
On Fri, 3 Jan 2003, Karl Schmidt wrote:

> Things are working normally except I have had mail bounce twice now with
> the following log message. The message was resent and the next time it
> went right through.
>
> I found the following in the receiving servers log:
>
> 2003-01-02 13:09:17 SMTP call from [123.45.67.89] dropped: too many
> nonmail commands (last was EHLO)


The patch below should fix this problem. It will be in the next release.

--
Philip Hazel            University of Cambridge Computing Service,
ph10@???      Cambridge, England. Phone: +44 1223 334714.




*** exim-4.12/src/smtp_in.c Wed Dec 18 10:28:04 2002
--- smtp_in.c    Wed Jan 22 12:25:26 2003
***************
*** 96,112 ****


static uschar *cmd_buffer;

! /* We need to know the position of RSET, HELO, EHLO, and STARTTLS. Their final
! fields are forced TRUE at the start of a new message setup, to allow one of
! each between messages that is not counted as a nonmail command. (In fact, only
! one of HELO/EHLO is not counted.) QUIT is "falsely" labelled as a mail command
! so that it doesn't up the count of non-mail commands and possibly provoke an
! error. */

  static smtp_cmd_list cmd_list[] = {
    { "rset",       sizeof("rset")-1,       RSET_CMD, FALSE, FALSE },  /* First */
    { "helo",       sizeof("helo")-1,       HELO_CMD, TRUE,  FALSE },
    { "ehlo",       sizeof("ehlo")-1,       EHLO_CMD, TRUE,  FALSE },
    #ifdef SUPPORT_TLS
    { "starttls",   sizeof("starttls")-1,   STARTTLS_CMD, FALSE, FALSE },
    #endif
--- 96,121 ----


static uschar *cmd_buffer;

! /* We need to know the position of RSET, HELO, EHLO, AUTH, and STARTTLS. Their
! final fields of all except AUTH are forced TRUE at the start of a new message
! setup, to allow one of each between messages that is not counted as a nonmail
! command. (In fact, only one of HELO/EHLO is not counted.) Also, we have to
! allow a new EHLO after starting up TLS.

+ AUTH is "falsely" labelled as a mail command initially, so that it doesn't get
+ counted. However, the flag is changed when AUTH is received, so that multiple
+ failing AUTHs will eventually hit the limit. After a successful AUTH, another
+ AUTH is already forbidden. After a TLS session is started, AUTH's flag is again
+ forced TRUE, to allow for the re-authentication that can happen at that point.
+
+ QUIT is also "falsely" labelled as a mail command so that it doesn't up the
+ count of non-mail commands and possibly provoke an error. */
+
  static smtp_cmd_list cmd_list[] = {
    { "rset",       sizeof("rset")-1,       RSET_CMD, FALSE, FALSE },  /* First */
    { "helo",       sizeof("helo")-1,       HELO_CMD, TRUE,  FALSE },
    { "ehlo",       sizeof("ehlo")-1,       EHLO_CMD, TRUE,  FALSE },
+   { "auth",       sizeof("auth")-1,       AUTH_CMD, TRUE,  TRUE  },
    #ifdef SUPPORT_TLS
    { "starttls",   sizeof("starttls")-1,   STARTTLS_CMD, FALSE, FALSE },
    #endif
***************
*** 113,125 ****


/* If you change anything above here, also fix the definitions below. */

!   { "mail from:", sizeof("mail from:")-1, MAIL_CMD, TRUE,  TRUE },
!   { "rcpt to:",   sizeof("rcpt to:")-1,   RCPT_CMD, TRUE,  TRUE },
!   { "data",       sizeof("data")-1,       DATA_CMD, FALSE, TRUE },
!   { "quit",       sizeof("quit")-1,       QUIT_CMD, FALSE, TRUE },
    { "noop",       sizeof("noop")-1,       NOOP_CMD, TRUE,  FALSE },
!   { "auth",       sizeof("auth")-1,       AUTH_CMD, TRUE,  FALSE },
!   { "etrn",       sizeof("etrn")-1,       ETRN_CMD, TRUE,  FALSE},
    { "vrfy",       sizeof("vrfy")-1,       VRFY_CMD, TRUE,  FALSE },
    { "expn",       sizeof("expn")-1,       EXPN_CMD, TRUE,  FALSE },
    { "help",       sizeof("help")-1,       HELP_CMD, TRUE,  FALSE }
--- 122,133 ----


/* If you change anything above here, also fix the definitions below. */

!   { "mail from:", sizeof("mail from:")-1, MAIL_CMD, TRUE,  TRUE  },
!   { "rcpt to:",   sizeof("rcpt to:")-1,   RCPT_CMD, TRUE,  TRUE  },
!   { "data",       sizeof("data")-1,       DATA_CMD, FALSE, TRUE  },
!   { "quit",       sizeof("quit")-1,       QUIT_CMD, FALSE, TRUE  },
    { "noop",       sizeof("noop")-1,       NOOP_CMD, TRUE,  FALSE },
!   { "etrn",       sizeof("etrn")-1,       ETRN_CMD, TRUE,  FALSE },
    { "vrfy",       sizeof("vrfy")-1,       VRFY_CMD, TRUE,  FALSE },
    { "expn",       sizeof("expn")-1,       EXPN_CMD, TRUE,  FALSE },
    { "help",       sizeof("help")-1,       HELP_CMD, TRUE,  FALSE }
***************
*** 131,137 ****
  #define CMD_LIST_RSET      0
  #define CMD_LIST_HELO      1
  #define CMD_LIST_EHLO      2
! #define CMD_LIST_STARTTLS  3


  static uschar *protocols[] = {
    US"local-smtp", US"local-esmtp", US"local-asmtp" };
--- 139,146 ----
  #define CMD_LIST_RSET      0
  #define CMD_LIST_HELO      1
  #define CMD_LIST_EHLO      2
! #define CMD_LIST_AUTH      3
! #define CMD_LIST_STARTTLS  4


  static uschar *protocols[] = {
    US"local-smtp", US"local-esmtp", US"local-asmtp" };
***************
*** 1725,1734 ****
      {
      /* The AUTH command is not permitted to occur inside a transaction, and may
      occur successfully only once per connection, and then only when we've
!     advertised it. */


      case AUTH_CMD:
      authentication_failed = TRUE;


      if (!auth_advertised)
        {
--- 1685,1701 ----
      {
      /* The AUTH command is not permitted to occur inside a transaction, and may
      occur successfully only once per connection, and then only when we've
!     advertised it. Actually, that isn't quite true. When TLS is started, all
!     previous information about a connection must be discarded, so a new AUTH is
!     permitted at that time.


+     AUTH is initially labelled as a "nonmail command" so that one occurrence
+     doesn't get counted. We change the label here so that multiple failing
+     AUTHS will eventually hit the nonmail threshold. */
+
      case AUTH_CMD:
      authentication_failed = TRUE;
+     cmd_list[CMD_LIST_AUTH].is_mail_cmd = FALSE;


      if (!auth_advertised)
        {
***************
*** 2751,2763 ****
      cmd_list[CMD_LIST_STARTTLS].is_mail_cmd = FALSE;


      /* Attempt to start up a TLS session, and if successful, discard all
!     knowledge that was obtained previously. One cause for failure is a nested
!     STARTTLS, in which case tls_active remains set, but we must still reject
!     all incoming commands. */


      if ((rc = tls_server_start()) == OK)
        {
        helo_seen = esmtp= FALSE;
        if (sender_helo_name != NULL)
          {
          store_free(sender_helo_name);
--- 2716,2730 ----
      cmd_list[CMD_LIST_STARTTLS].is_mail_cmd = FALSE;


      /* Attempt to start up a TLS session, and if successful, discard all
!     knowledge that was obtained previously. We must allow for an extra EHLO
!     command and an extra AUTH command after STARTTLS that don't add to the
!     nonmail command count. */


      if ((rc = tls_server_start()) == OK)
        {
        helo_seen = esmtp= FALSE;
+       cmd_list[CMD_LIST_EHLO].is_mail_cmd = TRUE;
+       cmd_list[CMD_LIST_AUTH].is_mail_cmd = TRUE;
        if (sender_helo_name != NULL)
          {
          store_free(sender_helo_name);