[exim-cvs] cvs commit: exim/exim-doc/doc-txt ChangeLog exim…

Top Page
Delete this message
Reply to this message
Author: Nigel Metheringham
Date:  
To: exim-cvs
Subject: [exim-cvs] cvs commit: exim/exim-doc/doc-txt ChangeLog exim/exim-src/src local_scan.h macros.h mytypes.h smtp_in.c verify.c
nm4 2008/09/29 12:41:07 BST

  Modified files:
    exim-doc/doc-txt     ChangeLog 
    exim-src/src         local_scan.h macros.h mytypes.h smtp_in.c 
                         verify.c 
  Log:
  Fix to EXPN not working under TLS.  Fixes bug #744


  Revision  Changes    Path
  1.554     +4 -1      exim/exim-doc/doc-txt/ChangeLog
  1.12      +4 -2      exim/exim-src/src/local_scan.h
  1.37      +15 -0     exim/exim-src/src/macros.h
  1.5       +2 -2      exim/exim-src/src/mytypes.h
  1.63      +20 -5     exim/exim-src/src/smtp_in.c
  1.52      +53 -16    exim/exim-src/src/verify.c


  Index: ChangeLog
  ===================================================================
  RCS file: /home/cvs/exim/exim-doc/doc-txt/ChangeLog,v
  retrieving revision 1.553
  retrieving revision 1.554
  diff -u -r1.553 -r1.554
  --- ChangeLog    5 Sep 2008 16:59:47 -0000    1.553
  +++ ChangeLog    29 Sep 2008 11:41:07 -0000    1.554
  @@ -1,4 +1,4 @@
  -$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.553 2008/09/05 16:59:47 fanf2 Exp $
  +$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.554 2008/09/29 11:41:07 nm4 Exp $


Change log file for Exim from version 4.21
-------------------------------------------
@@ -51,7 +51,7 @@

NM/05 Bugzilla 437: Prevent Maildix aux files being created with mode 000

  -NM/05 Bugzilla 598: Improvedment to Dovecot authenticator handling.
  +NM/05 Bugzilla 598: Improvement to Dovecot authenticator handling.
         Patch provided by Jan Srzednicki


   TF/05 Leading white space used to be stripped from $spam_report which
  @@ -68,6 +68,9 @@
   TF/09 Produce a more useful error message if an SMTP transport's hosts
         setting expands to an empty string.


  +NM/06 Bugzilla 744: EXPN did not work under TLS.
  +      Patch provided by Phil Pennock
  +


Exim version 4.69
-----------------

  Index: local_scan.h
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/local_scan.h,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- local_scan.h    14 Jun 2007 13:27:11 -0000    1.11
  +++ local_scan.h    29 Sep 2008 11:41:07 -0000    1.12
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/local_scan.h,v 1.11 2007/06/14 13:27:11 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/local_scan.h,v 1.12 2008/09/29 11:41:07 nm4 Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -17,6 +17,7 @@
   /* Some basic types that make some things easier, the Exim configuration
   settings, and the store functions. */


  +#include <stdarg.h>
   #include <sys/types.h>
   #include "config.h"
   #include "mytypes.h"
  @@ -167,7 +168,7 @@
   extern pid_t   child_open(uschar **, uschar **, int, int *, int *, BOOL);
   extern pid_t   child_open_exim(int *);
   extern pid_t   child_open_exim2(int *, uschar *, uschar *);
  -extern void    debug_printf(char *, ...) PRINTF_FUNCTION;
  +extern void    debug_printf(char *, ...) PRINTF_FUNCTION(1,2);
   extern uschar *expand_string(uschar *);
   extern void    header_add(int, char *, ...);
   extern void    header_add_at_position(BOOL, uschar *, BOOL, int, char *, ...);
  @@ -185,7 +186,8 @@
   extern BOOL    receive_remove_recipient(uschar *);
   extern uschar *rfc2047_decode(uschar *, BOOL, uschar *, int, int *, uschar **);
   extern int     smtp_fflush(void);
  -extern void    smtp_printf(char *, ...) PRINTF_FUNCTION;
  +extern void    smtp_printf(char *, ...) PRINTF_FUNCTION(1,2);
  +extern void    smtp_vprintf(char *, va_list);
   extern uschar *string_copy(uschar *);
   extern uschar *string_copyn(uschar *, int);
   extern uschar *string_sprintf(char *, ...);


  Index: macros.h
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/macros.h,v
  retrieving revision 1.36
  retrieving revision 1.37
  diff -u -r1.36 -r1.37
  --- macros.h    22 Aug 2007 10:10:23 -0000    1.36
  +++ macros.h    29 Sep 2008 11:41:07 -0000    1.37
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/macros.h,v 1.36 2007/08/22 10:10:23 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/macros.h,v 1.37 2008/09/29 11:41:07 nm4 Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -840,4 +840,19 @@


enum { FILTER_UNSET, FILTER_FORWARD, FILTER_EXIM, FILTER_SIEVE };

+/* C99 defines va_copy() for copying a varargs ap so that it can be reused,
+since on some platforms multiple iterations of va_start()/va_end() are not
+supported. But va_copy() is itself not so portable. Hack around it.
+See portability notes at: http://unixpapa.com/incnote/variadic.html */
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+/* va_copy exists for us or the system is broken and we need OS hacks */
+#elif defined(va_copy)
+/* trust it; hope that va_copy is always a macro when defined */
+#elif !defined(va_copy) && defined(__va_copy)
+#define va_copy(dest, src) __va_copy(dest, src)
+#else
+#define va_copy(dest, src) do { memcpy(dest, src, sizeof(va_list) } while (0)
+#endif
+
/* End of macros.h */

  Index: mytypes.h
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/mytypes.h,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- mytypes.h    8 Jan 2007 10:50:18 -0000    1.4
  +++ mytypes.h    29 Sep 2008 11:41:07 -0000    1.5
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/mytypes.h,v 1.4 2007/01/08 10:50:18 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/mytypes.h,v 1.5 2008/09/29 11:41:07 nm4 Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -25,9 +25,9 @@
   the arguments of printf-like functions. This is done by a macro. */


#ifdef __GNUC__
-#define PRINTF_FUNCTION __attribute__((format(printf,1,2)))
+#define PRINTF_FUNCTION(A,B) __attribute__((format(printf,A,B)))
#else
-#define PRINTF_FUNCTION
+#define PRINTF_FUNCTION(A,B)
#endif



  Index: smtp_in.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/smtp_in.c,v
  retrieving revision 1.62
  retrieving revision 1.63
  diff -u -r1.62 -r1.63
  --- smtp_in.c    28 Sep 2007 12:21:57 -0000    1.62
  +++ smtp_in.c    29 Sep 2008 11:41:07 -0000    1.63
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/smtp_in.c,v 1.62 2007/09/28 12:21:57 tom Exp $ */
  +/* $Cambridge: exim/exim-src/src/smtp_in.c,v 1.63 2008/09/29 11:41:07 nm4 Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -376,26 +376,41 @@
   {
   va_list ap;


  +va_start(ap, format);
  +smtp_vprintf(format, ap);
  +va_end(ap);
  +}
  +
  +/* This is split off so that verify.c:respond_printf() can, in effect, call
  +smtp_printf(), bearing in mind that in C a vararg function can't directly
  +call another vararg function, only a function which accepts a va_list.
  +
  +Note also that repeated calls to va_start()/va_end() pairs is claimed to be
  +non-portable; meanwhile, va_copy() is also non-portable in that it's C99, so
  +we end up needing OS support to define it for us. */
  +
  +void
  +smtp_vprintf(char *format, va_list ap)
  +{
  +va_list ap_d;
  +
   DEBUG(D_receive)
     {
     uschar *cr, *end;
  -  va_start(ap, format);
  -  (void) string_vformat(big_buffer, big_buffer_size, format, ap);
  -  va_end(ap);
  +  va_copy(ap_d, ap);
  +  (void) string_vformat(big_buffer, big_buffer_size, format, ap_d);
     end = big_buffer + Ustrlen(big_buffer);
     while ((cr = Ustrchr(big_buffer, '\r')) != NULL)   /* lose CRs */
       memmove(cr, cr + 1, (end--) - cr);
     debug_printf("SMTP>> %s", big_buffer);
     }


  -va_start(ap, format);
   if (!string_vformat(big_buffer, big_buffer_size, format, ap))
     {
     log_write(0, LOG_MAIN|LOG_PANIC, "string too large in smtp_printf()");
     smtp_closedown(US"Unexpected error");
     exim_exit(EXIT_FAILURE);
     }
  -va_end(ap);


/* If this is the first output for a (non-batch) RCPT command, see if all RCPTs
have had the same. Note: this code is also present in smtp_respond(). It would

  Index: verify.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/verify.c,v
  retrieving revision 1.51
  retrieving revision 1.52
  diff -u -r1.51 -r1.52
  --- verify.c    14 Jun 2007 14:18:19 -0000    1.51
  +++ verify.c    29 Sep 2008 11:41:07 -0000    1.52
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/verify.c,v 1.51 2007/06/14 14:18:19 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/verify.c,v 1.52 2008/09/29 11:41:07 nm4 Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -863,6 +863,42 @@




  +/**************************************************
  +* printf that automatically handles TLS if needed *
  +***************************************************/
  +
  +/* This function is used by verify_address() as a substitute for all fprintf()
  +calls; a direct fprintf() will not produce output in a TLS SMTP session, such
  +as a response to an EXPN command.  smtp_in.c makes smtp_printf available but
  +that assumes that we always use the smtp_out FILE* when not using TLS or the
  +ssl buffer when we are.  Instead we take a FILE* parameter and check to see if
  +that is smtp_out; if so, smtp_printf() with TLS support, otherwise regular
  +fprintf().
  +
  +Arguments:
  +  f           the candidate FILE* to write to
  +  format      format string
  +  ...         optional arguments
  +
  +Returns:
  +              nothing
  +*/
  +
  +static void PRINTF_FUNCTION(2,3)
  +respond_printf(FILE *f, char *format, ...)
  +{
  +va_list ap;
  +
  +va_start(ap, format);
  +if (smtp_out && (f == smtp_out))
  +  smtp_vprintf(format, ap);
  +else
  +  fprintf(f, format, ap);
  +va_end(ap);
  +}
  +
  +
  +
   /*************************************************
   *            Verify an email address             *
   *************************************************/
  @@ -962,8 +998,8 @@
     if ((options & vopt_qualify) == 0)
       {
       if (f != NULL)
  -      fprintf(f, "%sA domain is required for \"%s\"%s\n", ko_prefix, address,
  -        cr);
  +      respond_printf(f, "%sA domain is required for \"%s\"%s\n",
  +        ko_prefix, address, cr);
       *failure_ptr = US"qualify";
       return FAIL;
       }
  @@ -1227,24 +1263,25 @@
         {
         address_item *p = addr->parent;


  -      fprintf(f, "%s%s %s", ko_prefix, full_info? addr->address : address,
  +      respond_printf(f, "%s%s %s", ko_prefix,
  +        full_info? addr->address : address,
           address_test_mode? "is undeliverable" : "failed to verify");
         if (!expn && admin_user)
           {
           if (addr->basic_errno > 0)
  -          fprintf(f, ": %s", strerror(addr->basic_errno));
  +          respond_printf(f, ": %s", strerror(addr->basic_errno));
           if (addr->message != NULL)
  -          fprintf(f, ": %s", addr->message);
  +          respond_printf(f, ": %s", addr->message);
           }


         /* Show parents iff doing full info */


         if (full_info) while (p != NULL)
           {
  -        fprintf(f, "%s\n    <-- %s", cr, p->address);
  +        respond_printf(f, "%s\n    <-- %s", cr, p->address);
           p = p->parent;
           }
  -      fprintf(f, "%s\n", cr);
  +      respond_printf(f, "%s\n", cr);
         }


       if (!full_info) return copy_error(vaddr, addr, FAIL);
  @@ -1259,26 +1296,26 @@
       if (f != NULL)
         {
         address_item *p = addr->parent;
  -      fprintf(f, "%s%s cannot be resolved at this time", ko_prefix,
  +      respond_printf(f, "%s%s cannot be resolved at this time", ko_prefix,
           full_info? addr->address : address);
         if (!expn && admin_user)
           {
           if (addr->basic_errno > 0)
  -          fprintf(f, ": %s", strerror(addr->basic_errno));
  +          respond_printf(f, ": %s", strerror(addr->basic_errno));
           if (addr->message != NULL)
  -          fprintf(f, ": %s", addr->message);
  +          respond_printf(f, ": %s", addr->message);
           else if (addr->basic_errno <= 0)
  -          fprintf(f, ": unknown error");
  +          respond_printf(f, ": unknown error");
           }


         /* Show parents iff doing full info */


         if (full_info) while (p != NULL)
           {
  -        fprintf(f, "%s\n    <-- %s", cr, p->address);
  +        respond_printf(f, "%s\n    <-- %s", cr, p->address);
           p = p->parent;
           }
  -      fprintf(f, "%s\n", cr);
  +      respond_printf(f, "%s\n", cr);
         }
       if (!full_info) return copy_error(vaddr, addr, DEFER);
         else if (yield == OK) yield = DEFER;
  @@ -1293,16 +1330,16 @@
       if (addr_new == NULL)
         {
         if (addr_local == NULL && addr_remote == NULL)
  -        fprintf(f, "250 mail to <%s> is discarded\r\n", address);
  +        respond_printf(f, "250 mail to <%s> is discarded\r\n", address);
         else
  -        fprintf(f, "250 <%s>\r\n", address);
  +        respond_printf(f, "250 <%s>\r\n", address);
         }
       else while (addr_new != NULL)
         {
         address_item *addr2 = addr_new;
         addr_new = addr2->next;
         if (addr_new == NULL) ok_prefix = US"250 ";
  -      fprintf(f, "%s<%s>\r\n", ok_prefix, addr2->address);
  +      respond_printf(f, "%s<%s>\r\n", ok_prefix, addr2->address);
         }
       return OK;
       }