Changeset 214 for trunk/src/sh_mail.c


Ignore:
Timestamp:
Feb 17, 2009, 10:54:26 PM (16 years ago)
Author:
katerina
Message:

Rewrite mail subsystem for more flexibility (closes ticket #141).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/sh_mail.c

    r210 r214  
    5959#include "sh_tools.h"
    6060#include "sh_pthread.h"
     61#include "sh_mail_int.h"
     62#include "sh_nmail.h"
    6163
    6264#undef  FIL__
     
    6769static int failedMail = SL_FALSE;
    6870
    69 /* MX Resolver Struct
    70  */
    71 typedef struct mx_ {
    72   int    pref;
    73   char * address;
    74 } mx;
    75 
    76 typedef struct dnsrep_ {
    77   int    count;
    78   mx   * reply;
    79 } dnsrep;
    80 
    81 static int free_mx (dnsrep * answers);
    8271static dnsrep * return_mx (char *domain);
    8372
     
    258247}
    259248
    260 #define SH_FILT_NUM 32
    261 #define SH_FILT_OR  0
    262 #define SH_FILT_AND 1
    263 #define SH_FILT_NOT 2
    264 #define SH_FILT_INIT { 0, { NULL }, 0, { NULL }, 0, { NULL }}
    265 
    266 typedef struct _sh_filter_type
    267 {
    268   int      for_c;
    269   char   * for_v[SH_FILT_NUM];
    270   int      fand_c;
    271   char   * fand_v[SH_FILT_NUM];
    272   int      fnot_c;
    273   char   * fnot_v[SH_FILT_NUM];
    274 
    275 } sh_filter_type;
    276 
    277 static
     249void sh_filter_filterfree (sh_filter_type * filter)
     250{
     251  int i;
     252
     253  if (filter)
     254    {
     255      for (i = 0; i < filter->for_c; ++i) {
     256        if (filter->for_v[i])
     257          SH_FREE(filter->for_v[i]);
     258        filter->for_v[i] = NULL;
     259      }
     260      filter->for_c = 0;
     261      for (i = 0; i < filter->fand_c; ++i) {
     262        if (filter->fand_v[i])
     263          SH_FREE(filter->fand_v[i]);
     264        filter->fand_v[i] = NULL;
     265      }
     266      filter->fand_c = 0;
     267      for (i = 0; i < filter->fnot_c; ++i) {
     268        if (filter->fnot_v[i])
     269          SH_FREE(filter->fnot_v[i]);
     270        filter->fnot_v[i] = NULL;
     271      }
     272      filter->fnot_c = 0;
     273    }
     274}
     275
    278276int sh_filter_filteradd (const char * argstring,
    279277                         sh_filter_type * filter, int ftype)
     
    375373
    376374/*
    377  * -- check filters
    378  */
    379 static
     375 * -- Check filters. Returns 0 if message passes.
     376 */
    380377int sh_filter_filter (const char * message, sh_filter_type * filter)
    381378{
    382379  int i;
    383   int j = 0;
    384 
    385   SL_ENTER(_("sh_mail_filter"));
    386 
    387   /* Presence of any of these keywords prevents execution.
    388    */
    389   if (filter->fnot_c > 0)
    390     {
    391       for (i = 0; i < filter->fnot_c; ++i)
    392         {
    393           if (NULL != sl_strstr(message, filter->fnot_v[i]))
     380
     381  SL_ENTER(_("sh_filter_filter"));
     382
     383  if (filter)
     384    {
     385
     386      /* Presence of any of these keywords prevents execution.
     387       */
     388      if (filter->fnot_c > 0)
     389        {
     390          for (i = 0; i < filter->fnot_c; ++i)
    394391            {
    395               SL_RETURN ((-1), _("sh_filter_filter"));
     392              if (NULL != sl_strstr(message, filter->fnot_v[i]))
     393                {
     394                  SL_RETURN ((-1), _("sh_filter_filter"));
     395                }
    396396            }
    397397        }
    398     }
    399 
    400   /* Presence of all of these keywords is required for execution.
    401    */
    402   if (filter->fand_c > 0)
    403     {
    404       j = 0;
    405 
    406       for (i = 0; i < filter->fand_c; ++i)
    407         if (NULL != sl_strstr(message, filter->fand_v[i]))
    408           ++j;
    409 
    410       if (j != filter->fand_c)
    411         {
     398     
     399      /* Presence of all of these keywords is required for execution.
     400       */
     401      if (filter->fand_c > 0)
     402        {
     403          for (i = 0; i < filter->fand_c; ++i)
     404            {
     405              if (NULL == sl_strstr(message, filter->fand_v[i]))
     406                {
     407                  SL_RETURN ((-1), _("sh_filter_filter"));
     408                }
     409            }
     410        }
     411     
     412      /* Presence of at least one of these keywords is required for execution.
     413       */
     414      if (filter->for_c > 0)
     415        {
     416          for (i = 0; i < filter->for_c; ++i)
     417            {
     418              if (NULL != sl_strstr(message, filter->for_v[i]))
     419                {
     420                  goto isok;
     421                }
     422            }
    412423          SL_RETURN ((-1), _("sh_filter_filter"));
    413424        }
    414     }
    415 
    416   /* Presence of at least one of these keywords is required for execution.
    417    */
    418   if (filter->for_c > 0)
    419     {
    420       for (i = 0; i < filter->for_c; ++i)
    421         {
    422           if (NULL != sl_strstr(message, filter->for_v[i]))
    423             {
    424               goto isok;
    425             }
    426         }
    427       SL_RETURN ((-1), _("sh_filter_filter"));
    428425    }
    429426
    430427 isok:
    431428  SL_RETURN ((0), _("sh_filter_filter"));
    432 }
    433 
    434 
    435 static sh_filter_type mail_filter = SH_FILT_INIT;
    436 
    437 /*
    438  * -- add keywords to the OR filter
    439  */
    440 int sh_mail_add_or (const char * str)
    441 {
    442   return (sh_filter_filteradd (str, &(mail_filter), SH_FILT_OR));
    443 }
    444 
    445 /*
    446  * -- add keywords to the AND filter
    447  */
    448 int sh_mail_add_and (const char * str)
    449 {
    450   return (sh_filter_filteradd (str, &(mail_filter), SH_FILT_AND));
    451 }
    452 
    453 /*
    454  * -- add keywords to the NOT filter
    455  */
    456 int sh_mail_add_not (const char * str)
    457 {
    458   return (sh_filter_filteradd (str, &(mail_filter), SH_FILT_NOT));
    459 }
    460 
    461 
    462 static char * address_list[8] = {
    463   NULL, NULL, NULL, NULL,
    464   NULL, NULL, NULL, NULL
    465 };
    466 
    467 static   int   address_num = 0;
    468 static   int   address_num_compiled = 0;
    469 static   int   setaddress_compiled = S_FALSE;
    470 
    471 void reset_count_dev_mail(void)
    472 {
    473   /* if not, then we still have the compiled-in address (if any), so we
    474    * don' touch them
    475    */
    476   if (address_num_compiled == -99)
    477     address_num = 0;
    478   return;
    479 }
    480 
    481 int sh_mail_setaddress (const char * address)
    482 {
    483   char     *     p;
    484 
    485   SL_ENTER(_("sh_mail_setaddress"));
    486  
    487   if (0 == strcmp(address, _("NULL")))
    488     SL_RETURN ( (0), _("sh_mail_setaddress"));
    489    
    490   if (address != NULL && address_num < (2 * SH_PATHBUF / 64 ))
    491     {
    492       if (address_num < (SH_PATHBUF / 64 ))
    493         p = &sh.srvmail.name[address_num*64];
    494       else
    495         p = &sh.srvmail.alt[address_num*64];
    496 
    497       (void) sl_strlcpy (p, address, 64);
    498      
    499       if ((p == NULL) || ( sl_strlen(address) != sl_strlen(p)))
    500         {
    501           memset(p, (int)'\0', 64);
    502           SL_RETURN ( (-1), _("sh_mail_setaddress"));
    503         }
    504       address_list[address_num] = p;
    505 #if 0
    506       if (!sl_is_suid())
    507         {
    508           TPT(( 0, FIL__, __LINE__, _("msg=<address_list[%d] = %s>\n"),
    509                 address_num, address_list[address_num]));
    510         }
    511 #endif
    512       if (setaddress_compiled == S_TRUE)
    513         {
    514           ++address_num;
    515           ++address_num_compiled;
    516         }
    517       else
    518         {
    519           if (address_num == address_num_compiled)
    520             {
    521               address_num = 0;
    522               address_num_compiled = -99;
    523             }
    524           ++address_num;
    525         }
    526       SL_RETURN ( (0), _("sh_mail_setaddress"));
    527     }
    528   SL_RETURN ( (-1), _("sh_mail_setaddress"));
    529 }
    530 
    531 int sh_mail_setaddress_int (const char * address)
    532 {
    533   int i;
    534   SL_ENTER(_("sh_mail_setaddress_int"));
    535   setaddress_compiled = S_TRUE;
    536   i = sh_mail_setaddress(address);
    537   setaddress_compiled = S_FALSE;
    538   SL_RETURN(i, _("sh_mail_setaddress_int"));
    539429}
    540430
     
    553443
    554444
    555 static int all_in_one = S_FALSE;
     445int sh_mail_all_in_one = S_FALSE;
    556446
    557447int sh_mail_setFlag (const char * str)
     
    559449  int i;
    560450  SL_ENTER(_("sh_mail_setFlag"));
    561   i = sh_util_flagval(str, &all_in_one);
     451  i = sh_util_flagval(str, &sh_mail_all_in_one);
    562452  SL_RETURN(i, _("sh_mail_setFlag"));
    563453}
     
    584474}
    585475
    586 
    587 static SH_FIFO * fifo_mail = NULL;
     476SH_MUTEX_INIT(mutex_fifo_mail, PTHREAD_MUTEX_INITIALIZER);
     477
     478SH_FIFO * fifo_mail = NULL;
    588479
    589480static
     
    598489    SL_RET0(_("sh_mail_emptystack"));
    599490
     491  SH_MUTEX_LOCK(mutex_fifo_mail);
    600492  while (NULL != (msg = pop_list(fifo_mail)))
    601493    {
     
    604496      SH_FREE(msg);
    605497    }
     498  SH_MUTEX_UNLOCK(mutex_fifo_mail);
    606499
    607500  SL_RET0(_("sh_mail_emptystack"));
     
    610503/* insert "\r\n" after each 998 char
    611504 */
    612 static char * split_string(char * str);
    613 
    614 int sh_mail_pushstack (/*@null@*/char * msg)
     505static char * split_string(const char * str);
     506
     507/* fixes warning: variable ‘p’ might be clobbered by ‘longjmp’ or ‘vfork’*/
     508static char ** p_dummy;
     509
     510int sh_mail_pushstack (int severity, const char * msg, const char * alias)
    615511{
    616512  char * p;
    617   int    retval = 0;
     513  volatile int    retval = 0;
    618514  int    status;
    619515
    620516  SL_ENTER(_("sh_mail_pushstack"));
    621517
    622   if (msg == NULL || failedMail == SL_TRUE || sh.srvmail.name[0] == '\0')
     518  if (msg == NULL || failedMail == SL_TRUE /* || sh.srvmail.name[0] == '\0' */)
    623519    SL_RETURN((0), (_("sh_mail_pushstack")));
    624520
    625   if (0 != sh_filter_filter(msg, &mail_filter))
    626     SL_RETURN((0), (_("sh_mail_pushstack")));
    627 
    628 #if 0
    629   if (msg != NULL && sl_strlen(msg) > 998)  /* RFC 2822 */
    630     msg[998] = '\0';
    631 #endif
    632 
    633521  p = split_string(msg);
     522  /* fixes "variable ‘p’ might be clobbered by ‘longjmp’ or ‘vfork’" */
     523  p_dummy = &p;
     524
     525  SH_MUTEX_LOCK(mutex_fifo_mail);
    634526
    635527  if (fifo_mail == NULL)
     
    638530      fifo_init(fifo_mail);
    639531    }
    640 
    641   status = push_list (fifo_mail, p);
     532  status = push_list (fifo_mail, p, severity, alias);
     533  SH_MUTEX_UNLOCK(mutex_fifo_mail);
     534
    642535  if (status >= 0)
    643536    ++sh.mailNum.alarm_last;
     
    647540  if (sh.mailNum.alarm_last >= sh.mailNum.alarm_interval)
    648541    {
    649       BREAKEXIT(sh_mail_msg);
    650       retval = sh_mail_msg (NULL);
     542      BREAKEXIT(sh_nmail_flush);
     543      retval = sh_nmail_flush ();
    651544    }
    652545
     
    660553 */
    661554static int sh_mail_end_conn (FILE * connfile, int fd);
    662 static FILE * sh_mail_start_conn (int aFlag, int * fd);
     555static FILE * sh_mail_start_conn (struct alias * address, int * fd, int * anum);
    663556
    664557static
    665 void sh_mail_get_subject(char * message,
     558void sh_mail_get_subject(const char * message,
    666559                         char * mheader, size_t len)
    667560{
     
    677570  char * mptr;
    678571  char   sev[8];
     572  char * msg;
    679573
    680574  SL_ENTER(_("sh_mail_get_subject"));
     
    693587  /* fast forward to the important part
    694588   */
    695   mptr = (char*)sl_strstr(message, _("msg="));
     589  msg  = sh_util_strdup(message);
     590
     591  mptr = sl_strstr(msg, _("msg="));
    696592  if (mptr)
    697593    {
     
    700596    }
    701597  else
    702     rep_serv_tab[2].data_str   = message;
    703 
    704   mptr = (char*)sl_strstr(message, _("sev="));
     598    rep_serv_tab[2].data_str   = msg;
     599
     600  mptr = sl_strstr(msg, _("sev="));
    705601  if (mptr)
    706602    {
     
    714610  else
    715611    {
    716       mptr = message;
     612      mptr = msg;
    717613      sev[0] = *mptr; ++mptr;
    718614      sev[1] = *mptr; ++mptr;
     
    737633  (void) sl_strlcat(mheader, p, len);
    738634  SH_FREE(p);
     635  SH_FREE(msg);
    739636  SL_RET0(_("sh_mail_get_subject"));
    740637}
    741638
    742 
    743 #if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
    744 #include <sys/mman.h>
    745 #endif
    746 
    747 static char * sh_mail_realloc (char * inbuf, size_t * insize, size_t increase)
    748 {
    749   size_t newsize;
    750   char * outbuf = inbuf;
    751 
    752   SL_ENTER(_("sh_mail_realloc"));
    753 
    754   if (sl_ok_adds((*insize), 1))
    755     {
    756       newsize = (*insize) + 1;
    757 
    758       if (sl_ok_adds(newsize, increase))
    759         {
    760           newsize += increase;
    761 
    762           outbuf = SH_ALLOC(newsize);
    763           MLOCK(outbuf, newsize);
    764           (void) sl_strlcpy(outbuf, inbuf, newsize);
    765 
    766           memset (inbuf, 0, (*insize));
    767           MUNLOCK(inbuf, (*insize));
    768           SH_FREE(inbuf);
    769 
    770           *insize = newsize;
    771         }
    772     }
    773 
    774   SL_RETURN( (outbuf), _("sh_mail_realloc"));
    775 }
    776 
    777 int sh_mail_msg (/*@null@*/char * message)
     639void sh_mail_signature_block (sh_string  * sigMsg, char * recipient,
     640                              char * bufcompress)
     641{
     642  time_t         id_audit;
     643  char         * theSig;
     644  char ibuf[80];
     645  unsigned int count;
     646
     647  /* ------ signature block ------------------------------------ */
     648 
     649  sigMsg = sh_string_add_from_char(sigMsg,
     650                                   _("-----BEGIN SIGNATURE-----\r\n"));
     651 
     652  count  = sh_nmail_get_mailkey (recipient, skey->mailkey_new, KEY_LEN+1,
     653                                 &id_audit);
     654 
     655  if (count != 0)
     656    {
     657      char sigbuf[KEYBUF_SIZE];
     658     
     659      /* Sign the message with the signature key.
     660       */
     661      theSig = sh_util_siggen (skey->mailkey_new,
     662                               bufcompress, sl_strlen(bufcompress),
     663                               sigbuf, sizeof(sigbuf));
     664      sigMsg = sh_string_add_from_char(sigMsg, theSig);
     665    }
     666  else
     667    {
     668       /* reveal first signature key
     669       */
     670      /* flawfinder: ignore */
     671      (void) sl_strlcpy(skey->crypt, skey->mailkey_new, KEY_LEN+1);
     672     
     673      BREAKEXIT(sh_util_encode);
     674      /* flawfinder: ignore */
     675      sh_util_encode(skey->crypt, bufcompress, 0, 'A');
     676     
     677      /* flawfinder: ignore */
     678      sigMsg     = sh_string_add_from_char(sigMsg, skey->crypt);
     679     
     680      /* flawfinder: ignore */
     681      memset (skey->crypt, 0, KEY_LEN);
     682    }
     683
     684    sigMsg     = sh_string_add_from_char(sigMsg, "\r\n");
     685
     686    sl_snprintf(ibuf, sizeof(ibuf), _("%06u %010lu::%s\r\n"),
     687                count, (unsigned long) id_audit, sh.host.name);
     688
     689    sigMsg     = sh_string_add_from_char(sigMsg, ibuf);
     690    sigMsg     = sh_string_add_from_char(sigMsg, _("-----END MESSAGE-----"));
     691
     692    return;
     693}
     694
     695int sh_mail_msg (const char * message)
    778696{
    779697    char         subject[32+32+SH_MINIBUF+2+3+SH_PATHBUF];
    780698    char         mheader[32+32+SH_MINIBUF+2+3];
    781699
    782     char       * mailMsg;
    783     char       * popMsg;
    784     int          status = 0, errcount;
     700    sh_string  * mailMsg;
     701    sh_string  * compMsg;
     702    int          status = 0;
     703    volatile int errcount;
    785704    size_t       wrlen;
    786     int          i;
    787     int          num_popped = 0;
    788     int          retval = -1; 
     705    volatile int retval = -1; 
    789706
    790707    char       * bufcompress;
     708    size_t       compressed;
     709
    791710    static int   failcount = 0;
    792     static int   isfirst   = 1;
    793     static int   mailcount = 0;
    794711    FILE       * connfile  = NULL;
    795712
     
    797714    struct  sigaction  new_act;
    798715
    799     static  time_t id_audit  = 0;
    800716    static  time_t fail_time = 0;
    801717    static  time_t success_time = 0;
    802718
    803     static  int ma_block = 0;
    804 
    805719    int       ma_socket = -1;
    806720
    807     SH_FIFO * fifo_temp = NULL;
    808 
    809     char    * theSig;
    810     char    * theMsg = NULL;
     721    int            address_num = 0;
     722    sh_string    * theMsg = NULL;
    811723
    812724    /* #define SH_MAILBUF (256)    */
    813 #define SH_MAILBUF (8*4096)
    814 
    815     size_t    msgbufsize = SH_MAILBUF;
    816     size_t    combufsize = SH_MAILBUF;
     725#define SH_MAILBUF 4096
     726
    817727    char      timebuf[81];
    818     char hashbuf[KEYBUF_SIZE];
    819728
    820729    SL_ENTER(_("sh_mail_msg"));
    821730
    822     if (ma_block == 1)
    823       SL_RETURN( (0), _("sh_mail_msg"));
    824 
    825     /* Return if we cannot mail.
     731    /*
     732     * Return if we cannot mail.
    826733     */
    827734    if (failedMail == SL_TRUE)
    828735      SL_RETURN((-1), _("sh_mail_msg"));
    829736
    830     if (failedMail == SL_FALSE && address_list[0] == NULL)
    831       {
    832         TPT((0, FIL__, __LINE__,
    833              _("msg=<Mail error: no recipient address.>\n")));
    834         failedMail = SL_TRUE;
    835         SL_RETURN((-1), _("sh_mail_msg"));
    836       }
    837 
     737    /*
     738     * Final failure, can't mail for SH_MAX_FAIL hours.
     739     */
    838740    if ( (success_time > 0) && (fail_time > 0) &&
    839741         (time(NULL) - success_time) > 3600*SH_MAX_FAIL)
    840742      {
    841         ma_block = 1;
    842743        sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_SRV_FAIL,
    843                          _("mail"), address_list[0]);
    844         ma_block = 0;
     744                         _("mail"),
     745                         sh_string_str(all_recipients->recipient));
    845746        sh_mail_emptystack();
    846747        sh.mailNum.alarm_last = 0;
     
    849750      }
    850751
    851     /* Try at most each hour.
     752    /*
     753     * Try at most every three seconds to mail if there was a failure.
    852754     */
    853755    if ((fail_time > 0) && (time(NULL) - fail_time) < 3/*600*/)
     
    855757        if (failcount > 3)
    856758          {
    857             /* -- Save for later. --
     759            /* -- Save for later. Changed: done by caller. --
     760             *      sh_nmail_pushstack (severity, message, alias);
    858761             */
    859             sh_mail_pushstack (message);
    860762            ++failcount;
    861763           
     
    873775    fail_time = 0;
    874776
    875     /* -- Polling, empty queue. --
    876      */
    877     if (message == NULL && sh.mailNum.alarm_last == 0)
    878       SL_RETURN((-1), _("sh_mail_msg"));
    879 
    880     /* -- Filtered. --
    881      */
    882     if (message != NULL && 0 != sh_filter_filter(message, &mail_filter))
    883       SL_RETURN((-1), (_("sh_mail_msg")));
    884 
    885 
    886777
    887778    /* ---------  Build complete message. ------------------------ */
    888779
    889     theMsg = split_string(message);
     780    /* Don't flush the queue here, because tag_list doesn't know
     781     * how to filter messages. */
     782
     783    theMsg = sh_string_new_from_lchar(message, strlen(message));
    890784
    891785    /* ---------- Header  ---------------------------------------- */
     
    894788      {
    895789        (void) sl_strlcpy(mheader, _("Subject: "),       sizeof(mheader)-5);
    896         (void) sl_strlcat(mheader, sh_unix_time (0, timebuf, sizeof(timebuf)),
     790        (void) sl_strlcat(mheader,
     791                          sh_unix_time (0, timebuf, sizeof(timebuf)),
    897792                          sizeof(mheader)-5);
    898793        (void) sl_strlcat(mheader, " ",                  sizeof(mheader)-5);
     
    901796    else
    902797      {
    903        
    904         if (message == NULL)
    905           {
    906             theMsg  = pop_list(fifo_mail);
    907             message = theMsg;
    908             if (message)
    909               --sh.mailNum.alarm_last;
    910           }
    911798       
    912799        if (message)
     
    917804          {
    918805            (void) sl_strlcpy(mheader, _("Subject: "),     sizeof(mheader)-5);
    919             (void) sl_strlcat(mheader, sh_unix_time (0, timebuf, sizeof(timebuf)),
     806            (void) sl_strlcat(mheader,
     807                              sh_unix_time (0, timebuf, sizeof(timebuf)),
    920808                              sizeof(mheader)-5);
    921809            (void) sl_strlcat(mheader, " ",                sizeof(mheader)-5);
     
    937825
    938826
    939     mailMsg     = (char *) SH_ALLOC (msgbufsize);
    940     bufcompress = (char *) SH_ALLOC (combufsize);
    941 
    942     MLOCK(mailMsg     , msgbufsize);
    943     MLOCK(bufcompress , combufsize);
    944 
    945     (void) sl_strlcpy(mailMsg, mheader, msgbufsize);
     827    mailMsg     = sh_string_new (SH_MAILBUF);
     828    compMsg     = sh_string_new (SH_MAILBUF);
     829
     830    mailMsg     = sh_string_add_from_char(mailMsg, mheader);
     831    mailMsg     = sh_string_add_from_char(mailMsg,
     832                                          _("-----BEGIN MESSAGE-----\r\n"));
     833
     834    mailMsg     = sh_string_add_from_char(mailMsg, subject);
     835    mailMsg     = sh_string_add          (mailMsg, theMsg);
     836    mailMsg     = sh_string_add_from_char(mailMsg, "\r\n");
     837
     838    /* ---------- Compressed Message  ---------------------------- */
     839
     840    compMsg     = sh_string_add_from_char(compMsg, subject);
     841    compMsg     = sh_string_add          (compMsg, theMsg);
     842    compMsg     = sh_string_add_from_char(compMsg, "\r\n");
     843
     844    bufcompress = SH_ALLOC(sh_string_len(compMsg) + KEY_LEN + 1);
    946845    bufcompress[0] = '\0';
    947846
    948     (void) sl_strlcat(mailMsg, _("-----BEGIN MESSAGE-----\r\n"), msgbufsize);
    949     (void) sl_strlcat(mailMsg, subject, msgbufsize);
    950     (void) sh_util_compress (bufcompress, subject,
    951                              (combufsize - KEY_LEN - 1));
    952     if (message != NULL)
    953       {
    954         if ((sl_strlen(theMsg) + sl_strlen(mailMsg) + 1) >
    955             (msgbufsize-(4*KEY_LEN)))
    956           {
    957             mailMsg     = sh_mail_realloc(mailMsg,     
    958                                           &msgbufsize, sl_strlen(theMsg)+2);
    959             bufcompress = sh_mail_realloc(bufcompress,
    960                                           &combufsize, sl_strlen(theMsg));
    961           }
    962         (void) sl_strlcat(mailMsg,  theMsg, msgbufsize-(4*KEY_LEN));
    963         (void) sl_strlcat(mailMsg,  "\r\n", msgbufsize-(4*KEY_LEN));
    964 
    965         (void) sh_util_compress (bufcompress,  theMsg, combufsize-KEY_LEN-1);
    966       }
    967 
    968     if (sh.mailNum.alarm_last > 0)
    969       {
    970         fifo_temp = SH_ALLOC (sizeof(SH_FIFO));
    971         fifo_init (fifo_temp);
    972 
    973         while ( NULL != (popMsg = pop_list(fifo_mail)) )
    974           {
    975             (void) push_list (fifo_temp, popMsg);
    976 
    977             if ((sl_strlen(popMsg) + sl_strlen(mailMsg) + 1) >
    978                 (msgbufsize-(4*KEY_LEN)))
    979               {
    980                 mailMsg     = sh_mail_realloc(mailMsg,     
    981                                               &msgbufsize,
    982                                               sl_strlen(popMsg)+2);
    983                 bufcompress = sh_mail_realloc(bufcompress,
    984                                               &combufsize,
    985                                               sl_strlen(popMsg));
    986               }
    987 
    988             (void) sl_strlcat(mailMsg, popMsg, msgbufsize-(4*KEY_LEN));
    989             (void) sl_strlcat(mailMsg, "\r\n", msgbufsize-(4*KEY_LEN));
    990             (void) sh_util_compress(bufcompress, popMsg, combufsize-KEY_LEN-1);
    991             SH_FREE(popMsg);
    992             --sh.mailNum.alarm_last;
    993             ++num_popped;
    994           }
    995       }
    996 
    997     /* ------ signature block ------------------------------------ */
    998    
    999     (void) sl_strlcat(mailMsg, _("-----BEGIN SIGNATURE-----\r\n"), msgbufsize);
    1000 
    1001     /* Generate new signature key.
    1002      */
    1003     if (isfirst == 1)
    1004       {
    1005         BREAKEXIT(sh_util_keyinit);
    1006         (void) sh_util_keyinit (skey->mailkey_old, KEY_LEN+1);
    1007       }
    1008 
    1009     /* iterate the key
    1010      */
    1011     (void) sl_strlcpy(skey->mailkey_new,
    1012                       sh_tiger_hash (skey->mailkey_old, TIGER_DATA, KEY_LEN,
    1013                                      hashbuf, sizeof(hashbuf)),
    1014                       KEY_LEN+1);
    1015 
    1016     if (isfirst == 0)
    1017       {
    1018         char sigbuf[KEYBUF_SIZE];
    1019 
    1020         /* Sign the message with the signature key.
    1021          */
    1022         theSig = sh_util_siggen (skey->mailkey_new,
    1023                                  bufcompress, sl_strlen(bufcompress),
    1024                                  sigbuf, sizeof(sigbuf));
    1025         (void) sl_strlcat (mailMsg,
    1026                            theSig,
    1027                            msgbufsize);
    1028       }
    1029     else
    1030       {
    1031         id_audit = time (NULL);
    1032 
    1033         /* reveal first signature key
    1034          */
    1035         /* flawfinder: ignore */
    1036         (void) sl_strlcpy(skey->crypt, skey->mailkey_new, KEY_LEN+1);
    1037 
    1038         BREAKEXIT(sh_util_encode);
    1039         /* flawfinder: ignore */
    1040         sh_util_encode(skey->crypt, bufcompress, 0, 'A');
    1041 
    1042         /* flawfinder: ignore */
    1043         (void) sl_strlcat (mailMsg, skey->crypt, msgbufsize);
    1044         /* flawfinder: ignore */
    1045         memset (skey->crypt, 0, KEY_LEN);
    1046         isfirst = 0;
    1047       }
    1048     (void) sl_strlcat (mailMsg, "\r\n", msgbufsize);
    1049 
    1050     /* X(n) -> X(n-1)
    1051      */
    1052     (void) sl_strlcpy (skey->mailkey_old, skey->mailkey_new, KEY_LEN+1);
    1053 
    1054     sl_snprintf(subject, sizeof(subject), _("%06d %010ld::%s\r\n"),
    1055                 mailcount, (long) id_audit, sh.host.name);
    1056 
    1057     (void) sl_strlcat (mailMsg, subject, msgbufsize);
    1058     ++mailcount;
    1059 
    1060     (void) sl_strlcat (mailMsg, _("-----END MESSAGE-----"), msgbufsize);
    1061 
    1062 
     847    compressed = sh_util_compress (bufcompress,
     848                                   sh_string_str(compMsg),
     849                                   sh_string_len(compMsg) + 1);
    1063850
    1064851    /* ---------- Connect ---------------------------------------- */
    1065 
    1066 
    1067852
    1068853    /* -- Catch (ignore) 'broken pipe'.
     
    1074859    (void) sigaction (SIGPIPE, &new_act, &old_act);
    1075860
    1076     i        = 0;
    1077861    errcount = 0;
    1078862
    1079     if (all_in_one == S_FALSE)
     863    if (sh_mail_all_in_one == S_FALSE)
    1080864      {
    1081         while (address_list[i] != NULL && i < address_num)
     865        struct alias * address_list;
     866
     867        address_list = all_recipients;
     868
     869        while (address_list)
    1082870          {
    1083             connfile = sh_mail_start_conn (i, &ma_socket);
     871            if (address_list->send_mail == 1)
     872              {
     873                connfile = sh_mail_start_conn (address_list,
     874                                               &ma_socket, &address_num);
    1084875           
    1085             if (NULL != connfile)
    1086               {
    1087                 wrlen = fwrite (mailMsg, 1, sl_strlen(mailMsg),
    1088                                  connfile);
    1089                 wrlen -= sl_strlen(mailMsg);
    1090                 if (wrlen == 0)
    1091                   status = sh_mail_end_conn (connfile, ma_socket);
     876                if (NULL != connfile)
     877                  {
     878                    wrlen = fwrite (sh_string_str(mailMsg), 1,
     879                                    sh_string_len(mailMsg), connfile);
     880                    wrlen -= sh_string_len(mailMsg);
     881
     882                    if (wrlen == 0)
     883                      {
     884                        sh_string  * sigMsg  = sh_string_new (0);
     885
     886                        sh_mail_signature_block (sigMsg,
     887                                                 sh_string_str(address_list->recipient),
     888                                                 bufcompress);
     889
     890                        wrlen = fwrite (sh_string_str(sigMsg), 1,
     891                                        sh_string_len(sigMsg), connfile);
     892                        wrlen -= sh_string_len(sigMsg);
     893
     894                        sh_string_destroy(&sigMsg);
     895                      }
     896
     897                    if (wrlen == 0)
     898                      status = sh_mail_end_conn (connfile, ma_socket);
     899                    else
     900                      status = -1;
     901                  }
     902                if (NULL == connfile ||  status != 0)
     903                  {
     904                    sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_SRV_FAIL,
     905                                     _("mail"),
     906                                     sh_string_str(address_list->recipient));
     907                    ++errcount;
     908                    ++sh.statistics.mail_failed;
     909                  }
    1092910                else
    1093                   status = -1;
     911                  {
     912                    ++sh.statistics.mail_success;
     913                  }
     914               
     915                if (connfile != NULL)
     916                  {
     917                    (void) fclose (connfile);
     918                    connfile = NULL;
     919                  }
    1094920              }
    1095             if (NULL == connfile ||  status != 0)
    1096               {
    1097                 ma_block = 1;
    1098                 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_SRV_FAIL,
    1099                                  _("mail"), address_list[i]);
    1100                 ma_block = 0;
    1101                 ++errcount;
    1102                 ++sh.statistics.mail_failed;
    1103               }
    1104             else
    1105               {
    1106                 ++sh.statistics.mail_success;
    1107               }
    1108 
    1109             if (connfile != NULL)
    1110               {
    1111                 (void) fclose (connfile);
    1112                 connfile = NULL;
    1113               }
    1114             ++i;
     921            address_list = address_list->all_next;
    1115922          }
    1116923      }
    1117924    else
    1118925      {
    1119         connfile = sh_mail_start_conn ( -9 , &ma_socket);
    1120        
     926        connfile = sh_mail_start_conn (NULL, &ma_socket, &address_num);
     927
    1121928        if (NULL != connfile)
    1122929          {
    1123             wrlen = fwrite (mailMsg, 1, sl_strlen(mailMsg), connfile);
    1124             wrlen -= sl_strlen(mailMsg);
     930            wrlen = fwrite (sh_string_str(mailMsg), 1,
     931                            sh_string_len(mailMsg), connfile);
     932            wrlen -= sh_string_len(mailMsg);
     933
     934            if (wrlen == 0)
     935              {
     936                sh_string  * sigMsg  = sh_string_new (0);
     937               
     938                sh_mail_signature_block (sigMsg,
     939                                         NULL,
     940                                         bufcompress);
     941               
     942                wrlen = fwrite (sh_string_str(sigMsg), 1,
     943                                sh_string_len(sigMsg), connfile);
     944                wrlen -= sh_string_len(sigMsg);
     945               
     946                sh_string_destroy(&sigMsg);
     947              }
     948
    1125949            if (wrlen == 0)
    1126950              status = sh_mail_end_conn (connfile, ma_socket);
     
    1128952              status = -1;
    1129953          }
    1130         if (NULL == connfile ||  status != 0)
     954
     955        if (NULL == connfile || status != 0)
    1131956          {
    1132             ma_block = 1;
     957            struct alias* ma_address = all_recipients;
     958
     959            while (ma_address)
     960              {
     961                if (ma_address->send_mail == 1)
     962                  break;
     963                ma_address = ma_address->all_next;
     964              }
     965
    1133966            sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_SRV_FAIL,
    1134                              _("mail"), address_list[0]);
    1135             ma_block = 0;
     967                             _("mail"), sh_string_str(ma_address->recipient));
    1136968            errcount = address_num;
    1137969            ++sh.statistics.mail_failed;
     
    1148980          }
    1149981      }
    1150 
    1151982   
    1152     memset (bufcompress, 0, combufsize);
    1153     MUNLOCK(bufcompress , combufsize);
     983    memset (bufcompress, 0, compressed);
    1154984    SH_FREE(bufcompress);
    1155985
    1156     memset (mailMsg, 0, msgbufsize);
    1157     MUNLOCK(mailMsg , msgbufsize);
    1158     SH_FREE(mailMsg);
     986    memset (sh_string_str(mailMsg), 0, sh_string_len(mailMsg));
     987    memset (sh_string_str(compMsg), 0, sh_string_len(compMsg));
     988    memset (sh_string_str(theMsg),  0, sh_string_len(theMsg));
     989
     990    sh_string_destroy(&mailMsg);
     991    sh_string_destroy(&compMsg);
     992    sh_string_destroy(&theMsg);
    1159993
    1160994    /* --- Stay responsible for delivery in case of failure --- */
    1161995
    1162     if (errcount == address_num && fifo_temp != NULL)
     996    if (errcount == address_num)
    1163997      {
    1164         while ( (NULL != (popMsg = pop_list(fifo_temp))) )
    1165           {
    1166             if (push_list (fifo_mail, popMsg) >= 0)
    1167               ++sh.mailNum.alarm_last;
    1168             SH_FREE(popMsg);
    1169           }
    1170         if (message != NULL)
    1171           {
    1172             if (fifo_mail == NULL)
    1173               {
    1174                 fifo_mail = SH_ALLOC(sizeof(SH_FIFO));
    1175                 fifo_init(fifo_mail);
    1176               }
    1177             retval = push_list (fifo_mail,  theMsg);
    1178             if (retval >= 0)
    1179               ++sh.mailNum.alarm_last;
    1180             if (retval == SH_FIFO_MAX)
    1181               retval = -2;
    1182             else
    1183               retval = -1;
    1184           }
     998        rollback_list(fifo_mail);
     999        retval = -1;
    11851000      }
    1186     else if (fifo_temp != NULL)
     1001    else
    11871002      {
    1188         while ( (NULL != (popMsg = pop_list(fifo_temp))) )
    1189           {
    1190             SH_FREE(popMsg);
    1191           }
     1003        mark_list(fifo_mail);
    11921004      }
    1193     if (fifo_temp != NULL)
    1194       SH_FREE(fifo_temp);
    1195 
    1196     /*
    1197     if (connfile != NULL)
    1198       fclose (connfile);
    1199     */
    1200 
    1201     if (theMsg != NULL)
    1202       SH_FREE(theMsg);
    12031005
    12041006    /* --- Reset signal. ---
     
    12111013        SL_RETURN((retval), _("sh_mail_msg"));
    12121014      }
     1015
    12131016    success_time = time(NULL);
    12141017    failcount = 0;
     
    12981101 *
    12991102 * start connection
    1300  * for details on SMTP, see RFC 821
     1103 * for details on SMTP, see RFC 821
     1104 *
     1105 * If ma_address == NULL, will send to all marked with
     1106 * send_mail=1 in recipient list, else to ma_address.   
    13011107 */
    13021108
    13031109static time_t time_wait = 300;
    13041110
    1305 static FILE * sh_mail_start_conn (int aFlag, int * ma_socket)
     1111static FILE * sh_mail_start_conn (struct alias * ma_address,
     1112                                  int * ma_socket, int * anum)
    13061113{
    13071114  char       * address;
     1115  int          aFlag = 0;
    13081116
    13091117  int          ecount;
     
    13341142  time_wait  = 300;
    13351143
    1336   if (aFlag >= 0)
    1337     address = address_list[aFlag];
    1338   else
    1339     address = address_list[0];
    1340 
    1341   TPT(( 0, FIL__, __LINE__, _("msg=<aFlag %d address %s>\n"),
    1342         aFlag, address));
    1343 
    1344   /* -------   split adress ------------------  */
    1345 
    1346   if (0 == strcmp(address, _("NULL")))
     1144  if (ma_address == NULL)
     1145    {
     1146      aFlag = 1;
     1147      ma_address = all_recipients;
     1148
     1149      while (ma_address)
     1150        {
     1151          if (ma_address->send_mail == 1)
     1152            break;
     1153          ma_address = ma_address->all_next;
     1154        }
     1155    }
     1156
     1157  if (!ma_address)
    13471158    {
    13481159      SL_RETURN( NULL, _("sh_mail_start_conn"));
    13491160    }
    1350    
     1161
     1162  address = sh_string_str(ma_address->recipient);
     1163
     1164  TPT(( 0, FIL__, __LINE__, _("msg=<address %s>\n"),
     1165        address));
     1166
     1167  /* -------   split adress ------------------  */
     1168
    13511169  if (strchr (address, '@') == NULL) {
    13521170    (void) sl_strlcpy(ma_user,    address,     256);
     
    13581176      ++i;
    13591177    }
    1360 
     1178   
    13611179    /* adress[i] = '@'
    13621180     */
     
    13851203  else
    13861204    {
    1387       answers = return_mx (ma_machine);
     1205      answers = ma_address->mx_list;
     1206      if (!answers)
     1207        {
     1208          answers = return_mx (ma_machine);
     1209          ma_address->mx_list = answers;
     1210        }
     1211
    13881212      if (answers)
    13891213        {
     
    14021226                break;
    14031227            }
    1404           (void) free_mx(answers);
    14051228        }
    14061229      else
     
    15111334  /* tell them who to send mail to
    15121335   */
    1513   if (aFlag >= 0)
     1336  if (aFlag == 0)
    15141337    {
    15151338      TPT(( 0, FIL__, __LINE__,  _("msg=<RCPT TO:<%s>>%c%c"),
     
    15291352          SL_RETURN( NULL, _("sh_mail_start_conn"));
    15301353        }
     1354      *anum = 1;
    15311355    }
    15321356  else
    15331357    {
    1534       ecount = 0;
    1535       for (i = 0; i < address_num; ++i)
    1536         {
    1537           if (address_list[i] == NULL)  /* paranoia */
    1538             break;
     1358      int address_num = 0;
     1359      ecount      = 0;
     1360
     1361      ma_address = all_recipients;
     1362
     1363      while (ma_address)
     1364        {
     1365          if (ma_address->send_mail != 1)
     1366            {
     1367              ma_address = ma_address->next;
     1368              continue;
     1369            }
     1370
     1371          ++address_num;
     1372
    15391373          TPT(( 0, FIL__, __LINE__,  _("msg=<RCPT TO:<%s>>%c%c"),
    1540                 address_list[i], 13, 10));
     1374                sh_string_str(ma_address->recipient), 13, 10));
    15411375         
    15421376          (void) fflush(connFile);
    1543           fprintf(connFile, _("RCPT TO:<%s>%c%c"), address_list[i], 13, 10);
     1377          fprintf(connFile, _("RCPT TO:<%s>%c%c"),
     1378                  sh_string_str(ma_address->recipient), 13, 10);
    15441379          (void) fflush(connFile);
    15451380         
     
    15481383              sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_NET,
    15491384                              _("RCPT TO failed"), _("sh_mail_start_conn"),
    1550                               _("mail"), address_list[i]);
     1385                              _("mail"), sh_string_str(ma_address->recipient));
    15511386
    15521387              TPT(( 0, FIL__, __LINE__, _("msg=<Timeout.>\n")));
    15531388              ++ecount;
    15541389            }
    1555         }
     1390          ma_address = ma_address->next;
     1391        }
     1392
     1393      *anum += address_num;
     1394
    15561395      if (ecount == address_num)
    15571396        {
     
    17711610#define SPLIT_AT 998
    17721611
    1773 static char * split_string(char * str)
     1612static char * split_string(const char * str)
    17741613{
    17751614  size_t size;
     
    17781617
    17791618  char * p, * p0;
    1780   char * q;
     1619  const char * q;
    17811620
    17821621  if (!str)
     
    22052044}
    22062045
    2207 static int free_mx (dnsrep * answers)
     2046int free_mx (dnsrep * answers)
    22082047{
    22092048  mx     * result;
Note: See TracChangeset for help on using the changeset viewer.