Changeset 214 for trunk/src/sh_mail.c
- Timestamp:
- Feb 17, 2009, 10:54:26 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/sh_mail.c
r210 r214 59 59 #include "sh_tools.h" 60 60 #include "sh_pthread.h" 61 #include "sh_mail_int.h" 62 #include "sh_nmail.h" 61 63 62 64 #undef FIL__ … … 67 69 static int failedMail = SL_FALSE; 68 70 69 /* MX Resolver Struct70 */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);82 71 static dnsrep * return_mx (char *domain); 83 72 … … 258 247 } 259 248 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 249 void 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 278 276 int sh_filter_filteradd (const char * argstring, 279 277 sh_filter_type * filter, int ftype) … … 375 373 376 374 /* 377 * -- check filters 378 */ 379 static 375 * -- Check filters. Returns 0 if message passes. 376 */ 380 377 int sh_filter_filter (const char * message, sh_filter_type * filter) 381 378 { 382 379 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) 394 391 { 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 } 396 396 } 397 397 } 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 } 412 423 SL_RETURN ((-1), _("sh_filter_filter")); 413 424 } 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"));428 425 } 429 426 430 427 isok: 431 428 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 filter439 */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 filter447 */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 filter455 */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, NULL465 };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 we474 * don' touch them475 */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 else495 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 0506 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 #endif512 if (setaddress_compiled == S_TRUE)513 {514 ++address_num;515 ++address_num_compiled;516 }517 else518 {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"));539 429 } 540 430 … … 553 443 554 444 555 static intall_in_one = S_FALSE;445 int sh_mail_all_in_one = S_FALSE; 556 446 557 447 int sh_mail_setFlag (const char * str) … … 559 449 int i; 560 450 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); 562 452 SL_RETURN(i, _("sh_mail_setFlag")); 563 453 } … … 584 474 } 585 475 586 587 static SH_FIFO * fifo_mail = NULL; 476 SH_MUTEX_INIT(mutex_fifo_mail, PTHREAD_MUTEX_INITIALIZER); 477 478 SH_FIFO * fifo_mail = NULL; 588 479 589 480 static … … 598 489 SL_RET0(_("sh_mail_emptystack")); 599 490 491 SH_MUTEX_LOCK(mutex_fifo_mail); 600 492 while (NULL != (msg = pop_list(fifo_mail))) 601 493 { … … 604 496 SH_FREE(msg); 605 497 } 498 SH_MUTEX_UNLOCK(mutex_fifo_mail); 606 499 607 500 SL_RET0(_("sh_mail_emptystack")); … … 610 503 /* insert "\r\n" after each 998 char 611 504 */ 612 static char * split_string(char * str); 613 614 int sh_mail_pushstack (/*@null@*/char * msg) 505 static char * split_string(const char * str); 506 507 /* fixes warning: variable âpâ might be clobbered by âlongjmpâ or âvforkâ*/ 508 static char ** p_dummy; 509 510 int sh_mail_pushstack (int severity, const char * msg, const char * alias) 615 511 { 616 512 char * p; 617 int retval = 0;513 volatile int retval = 0; 618 514 int status; 619 515 620 516 SL_ENTER(_("sh_mail_pushstack")); 621 517 622 if (msg == NULL || failedMail == SL_TRUE || sh.srvmail.name[0] == '\0')518 if (msg == NULL || failedMail == SL_TRUE /* || sh.srvmail.name[0] == '\0' */) 623 519 SL_RETURN((0), (_("sh_mail_pushstack"))); 624 520 625 if (0 != sh_filter_filter(msg, &mail_filter))626 SL_RETURN((0), (_("sh_mail_pushstack")));627 628 #if 0629 if (msg != NULL && sl_strlen(msg) > 998) /* RFC 2822 */630 msg[998] = '\0';631 #endif632 633 521 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); 634 526 635 527 if (fifo_mail == NULL) … … 638 530 fifo_init(fifo_mail); 639 531 } 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 642 535 if (status >= 0) 643 536 ++sh.mailNum.alarm_last; … … 647 540 if (sh.mailNum.alarm_last >= sh.mailNum.alarm_interval) 648 541 { 649 BREAKEXIT(sh_ mail_msg);650 retval = sh_ mail_msg (NULL);542 BREAKEXIT(sh_nmail_flush); 543 retval = sh_nmail_flush (); 651 544 } 652 545 … … 660 553 */ 661 554 static int sh_mail_end_conn (FILE * connfile, int fd); 662 static FILE * sh_mail_start_conn ( int aFlag, int * fd);555 static FILE * sh_mail_start_conn (struct alias * address, int * fd, int * anum); 663 556 664 557 static 665 void sh_mail_get_subject(c har * message,558 void sh_mail_get_subject(const char * message, 666 559 char * mheader, size_t len) 667 560 { … … 677 570 char * mptr; 678 571 char sev[8]; 572 char * msg; 679 573 680 574 SL_ENTER(_("sh_mail_get_subject")); … … 693 587 /* fast forward to the important part 694 588 */ 695 mptr = (char*)sl_strstr(message, _("msg=")); 589 msg = sh_util_strdup(message); 590 591 mptr = sl_strstr(msg, _("msg=")); 696 592 if (mptr) 697 593 { … … 700 596 } 701 597 else 702 rep_serv_tab[2].data_str = m essage;703 704 mptr = (char*)sl_strstr(message, _("sev="));598 rep_serv_tab[2].data_str = msg; 599 600 mptr = sl_strstr(msg, _("sev=")); 705 601 if (mptr) 706 602 { … … 714 610 else 715 611 { 716 mptr = m essage;612 mptr = msg; 717 613 sev[0] = *mptr; ++mptr; 718 614 sev[1] = *mptr; ++mptr; … … 737 633 (void) sl_strlcat(mheader, p, len); 738 634 SH_FREE(p); 635 SH_FREE(msg); 739 636 SL_RET0(_("sh_mail_get_subject")); 740 637 } 741 638 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) 639 void 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 695 int sh_mail_msg (const char * message) 778 696 { 779 697 char subject[32+32+SH_MINIBUF+2+3+SH_PATHBUF]; 780 698 char mheader[32+32+SH_MINIBUF+2+3]; 781 699 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; 785 704 size_t wrlen; 786 int i; 787 int num_popped = 0; 788 int retval = -1; 705 volatile int retval = -1; 789 706 790 707 char * bufcompress; 708 size_t compressed; 709 791 710 static int failcount = 0; 792 static int isfirst = 1;793 static int mailcount = 0;794 711 FILE * connfile = NULL; 795 712 … … 797 714 struct sigaction new_act; 798 715 799 static time_t id_audit = 0;800 716 static time_t fail_time = 0; 801 717 static time_t success_time = 0; 802 718 803 static int ma_block = 0;804 805 719 int ma_socket = -1; 806 720 807 SH_FIFO * fifo_temp = NULL; 808 809 char * theSig; 810 char * theMsg = NULL; 721 int address_num = 0; 722 sh_string * theMsg = NULL; 811 723 812 724 /* #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 817 727 char timebuf[81]; 818 char hashbuf[KEYBUF_SIZE];819 728 820 729 SL_ENTER(_("sh_mail_msg")); 821 730 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. 826 733 */ 827 734 if (failedMail == SL_TRUE) 828 735 SL_RETURN((-1), _("sh_mail_msg")); 829 736 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 */ 838 740 if ( (success_time > 0) && (fail_time > 0) && 839 741 (time(NULL) - success_time) > 3600*SH_MAX_FAIL) 840 742 { 841 ma_block = 1;842 743 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)); 845 746 sh_mail_emptystack(); 846 747 sh.mailNum.alarm_last = 0; … … 849 750 } 850 751 851 /* Try at most each hour. 752 /* 753 * Try at most every three seconds to mail if there was a failure. 852 754 */ 853 755 if ((fail_time > 0) && (time(NULL) - fail_time) < 3/*600*/) … … 855 757 if (failcount > 3) 856 758 { 857 /* -- Save for later. -- 759 /* -- Save for later. Changed: done by caller. -- 760 * sh_nmail_pushstack (severity, message, alias); 858 761 */ 859 sh_mail_pushstack (message);860 762 ++failcount; 861 763 … … 873 775 fail_time = 0; 874 776 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 886 777 887 778 /* --------- Build complete message. ------------------------ */ 888 779 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)); 890 784 891 785 /* ---------- Header ---------------------------------------- */ … … 894 788 { 895 789 (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)), 897 792 sizeof(mheader)-5); 898 793 (void) sl_strlcat(mheader, " ", sizeof(mheader)-5); … … 901 796 else 902 797 { 903 904 if (message == NULL)905 {906 theMsg = pop_list(fifo_mail);907 message = theMsg;908 if (message)909 --sh.mailNum.alarm_last;910 }911 798 912 799 if (message) … … 917 804 { 918 805 (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)), 920 808 sizeof(mheader)-5); 921 809 (void) sl_strlcat(mheader, " ", sizeof(mheader)-5); … … 937 825 938 826 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); 946 845 bufcompress[0] = '\0'; 947 846 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); 1063 850 1064 851 /* ---------- Connect ---------------------------------------- */ 1065 1066 1067 852 1068 853 /* -- Catch (ignore) 'broken pipe'. … … 1074 859 (void) sigaction (SIGPIPE, &new_act, &old_act); 1075 860 1076 i = 0;1077 861 errcount = 0; 1078 862 1079 if ( all_in_one == S_FALSE)863 if (sh_mail_all_in_one == S_FALSE) 1080 864 { 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) 1082 870 { 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); 1084 875 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 } 1092 910 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 } 1094 920 } 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; 1115 922 } 1116 923 } 1117 924 else 1118 925 { 1119 connfile = sh_mail_start_conn ( -9 , &ma_socket);1120 926 connfile = sh_mail_start_conn (NULL, &ma_socket, &address_num); 927 1121 928 if (NULL != connfile) 1122 929 { 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 1125 949 if (wrlen == 0) 1126 950 status = sh_mail_end_conn (connfile, ma_socket); … … 1128 952 status = -1; 1129 953 } 1130 if (NULL == connfile || status != 0) 954 955 if (NULL == connfile || status != 0) 1131 956 { 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 1133 966 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)); 1136 968 errcount = address_num; 1137 969 ++sh.statistics.mail_failed; … … 1148 980 } 1149 981 } 1150 1151 982 1152 memset (bufcompress, 0, combufsize); 1153 MUNLOCK(bufcompress , combufsize); 983 memset (bufcompress, 0, compressed); 1154 984 SH_FREE(bufcompress); 1155 985 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); 1159 993 1160 994 /* --- Stay responsible for delivery in case of failure --- */ 1161 995 1162 if (errcount == address_num && fifo_temp != NULL)996 if (errcount == address_num) 1163 997 { 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; 1185 1000 } 1186 else if (fifo_temp != NULL)1001 else 1187 1002 { 1188 while ( (NULL != (popMsg = pop_list(fifo_temp))) ) 1189 { 1190 SH_FREE(popMsg); 1191 } 1003 mark_list(fifo_mail); 1192 1004 } 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);1203 1005 1204 1006 /* --- Reset signal. --- … … 1211 1013 SL_RETURN((retval), _("sh_mail_msg")); 1212 1014 } 1015 1213 1016 success_time = time(NULL); 1214 1017 failcount = 0; … … 1298 1101 * 1299 1102 * 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. 1301 1107 */ 1302 1108 1303 1109 static time_t time_wait = 300; 1304 1110 1305 static FILE * sh_mail_start_conn (int aFlag, int * ma_socket) 1111 static FILE * sh_mail_start_conn (struct alias * ma_address, 1112 int * ma_socket, int * anum) 1306 1113 { 1307 1114 char * address; 1115 int aFlag = 0; 1308 1116 1309 1117 int ecount; … … 1334 1142 time_wait = 300; 1335 1143 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) 1347 1158 { 1348 1159 SL_RETURN( NULL, _("sh_mail_start_conn")); 1349 1160 } 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 1351 1169 if (strchr (address, '@') == NULL) { 1352 1170 (void) sl_strlcpy(ma_user, address, 256); … … 1358 1176 ++i; 1359 1177 } 1360 1178 1361 1179 /* adress[i] = '@' 1362 1180 */ … … 1385 1203 else 1386 1204 { 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 1388 1212 if (answers) 1389 1213 { … … 1402 1226 break; 1403 1227 } 1404 (void) free_mx(answers);1405 1228 } 1406 1229 else … … 1511 1334 /* tell them who to send mail to 1512 1335 */ 1513 if (aFlag >= 0)1336 if (aFlag == 0) 1514 1337 { 1515 1338 TPT(( 0, FIL__, __LINE__, _("msg=<RCPT TO:<%s>>%c%c"), … … 1529 1352 SL_RETURN( NULL, _("sh_mail_start_conn")); 1530 1353 } 1354 *anum = 1; 1531 1355 } 1532 1356 else 1533 1357 { 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 1539 1373 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)); 1541 1375 1542 1376 (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); 1544 1379 (void) fflush(connFile); 1545 1380 … … 1548 1383 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_NET, 1549 1384 _("RCPT TO failed"), _("sh_mail_start_conn"), 1550 _("mail"), address_list[i]);1385 _("mail"), sh_string_str(ma_address->recipient)); 1551 1386 1552 1387 TPT(( 0, FIL__, __LINE__, _("msg=<Timeout.>\n"))); 1553 1388 ++ecount; 1554 1389 } 1555 } 1390 ma_address = ma_address->next; 1391 } 1392 1393 *anum += address_num; 1394 1556 1395 if (ecount == address_num) 1557 1396 { … … 1771 1610 #define SPLIT_AT 998 1772 1611 1773 static char * split_string(c har * str)1612 static char * split_string(const char * str) 1774 1613 { 1775 1614 size_t size; … … 1778 1617 1779 1618 char * p, * p0; 1780 c har * q;1619 const char * q; 1781 1620 1782 1621 if (!str) … … 2205 2044 } 2206 2045 2207 staticint free_mx (dnsrep * answers)2046 int free_mx (dnsrep * answers) 2208 2047 { 2209 2048 mx * result;
Note:
See TracChangeset
for help on using the changeset viewer.