comparison src/dnsbl.cpp @ 3:7e1eb343a825

updates to use dcc conf files
author carl
date Wed, 21 Apr 2004 12:52:29 -0700
parents 9bcd5ef11279
children 15a7e942adec
comparison
equal deleted inserted replaced
2:9bcd5ef11279 3:7e1eb343a825
70 sfsistat mlfi_envfrom(SMFICTX *ctx, char **argv); 70 sfsistat mlfi_envfrom(SMFICTX *ctx, char **argv);
71 sfsistat mlfi_envrcpt(SMFICTX *ctx, char **argv); 71 sfsistat mlfi_envrcpt(SMFICTX *ctx, char **argv);
72 sfsistat mlfi_eom_or_abort(SMFICTX *ctx); 72 sfsistat mlfi_eom_or_abort(SMFICTX *ctx);
73 sfsistat mlfi_close(SMFICTX *ctx); 73 sfsistat mlfi_close(SMFICTX *ctx);
74 } 74 }
75
76 #ifndef bool
77 # define bool int
78 # define TRUE 1
79 # define FALSE 0
80 #endif /* ! bool */
81 75
82 struct ltstr { 76 struct ltstr {
83 bool operator()(char* s1, char* s2) const { 77 bool operator()(char* s1, char* s2) const {
84 return strcmp(s1, s2) < 0; 78 return strcmp(s1, s2) < 0;
85 } 79 }
151 // predefined names 145 // predefined names
152 // 146 //
153 #define DEFAULT "default" 147 #define DEFAULT "default"
154 #define WHITE "white" 148 #define WHITE "white"
155 #define BLACK "black" 149 #define BLACK "black"
150 #define OK "ok"
151 #define MANY "many"
156 152
157 153
158 //////////////////////////////////////////////// 154 ////////////////////////////////////////////////
159 // mail filter private data, held for us by sendmail 155 // mail filter private data, held for us by sendmail
160 // 156 //
492 } 488 }
493 489
494 490
495 static void dumpit(from_map map); 491 static void dumpit(from_map map);
496 static void dumpit(from_map map) { 492 static void dumpit(from_map map) {
497 fprintf(stderr, "\n");
498 for (from_map::iterator i=map.begin(); i!=map.end(); i++) { 493 for (from_map::iterator i=map.begin(); i!=map.end(); i++) {
499 fprintf(stderr, "envfrom map %s\n", (*i).first); 494 char buf[2000];
495 snprintf(buf, sizeof(buf), "envelope from map for %s", (*i).first);
500 string_map *sm = (*i).second; 496 string_map *sm = (*i).second;
501 dumpit("envelope from", *sm); 497 dumpit(buf, *sm);
502 } 498 }
503 } 499 }
504 500
505 501
506 static void dumpit(); 502 static void dumpit(CONFIG &dc);
507 static void dumpit() { 503 static void dumpit(CONFIG &dc) {
508 CONFIG &dc = *config; 504 fprintf(stderr, "\ndnsbls\n");
509 fprintf(stderr, "dnsbls\n");
510 for (dnsblp_map::iterator i=dc.dnsbls.begin(); i!=dc.dnsbls.end(); i++) { 505 for (dnsblp_map::iterator i=dc.dnsbls.begin(); i!=dc.dnsbls.end(); i++) {
511 fprintf(stderr, "%s %s %s\n", (*i).first, (*i).second->suffix, (*i).second->message); 506 fprintf(stderr, "%s %s %s\n", (*i).first, (*i).second->suffix, (*i).second->message);
512 } 507 }
513 fprintf(stderr, "dnsbl_lists\n"); 508 fprintf(stderr, "\ndnsbl_lists\n");
514 for (dnsbllp_map::iterator i=dc.dnsblls.begin(); i!=dc.dnsblls.end(); i++) { 509 for (dnsbllp_map::iterator i=dc.dnsblls.begin(); i!=dc.dnsblls.end(); i++) {
515 char *name = (*i).first; 510 char *name = (*i).first;
516 DNSBLL &dl = *((*i).second); 511 DNSBLL &dl = *((*i).second);
517 fprintf(stderr, "%s", name); 512 fprintf(stderr, "%s", name);
518 for (DNSBLL::iterator j=dl.begin(); j!=dl.end(); j++) { 513 for (DNSBLL::iterator j=dl.begin(); j!=dl.end(); j++) {
519 DNSBL &d = **j; 514 DNSBL &d = **j;
520 fprintf(stderr, " %s", d.suffix); 515 fprintf(stderr, " %s", d.suffix);
521 } 516 }
522 fprintf(stderr, "\n"); 517 fprintf(stderr, "\n");
523 } 518 }
519 fprintf(stderr, "\nfiles\n");
520 for (string_list::iterator i=dc.config_files.begin(); i!=dc.config_files.end(); i++) {
521 char *f = *i;
522 fprintf(stderr, "config includes %s\n", f);
523 }
524 }
525
526
527 ////////////////////////////////////////////////
528 // check for redundant or recursive include files
529 //
530 static bool ok_to_include(CONFIG &dc, char *fn);
531 static bool ok_to_include(CONFIG &dc, char *fn) {
532 if (!fn) return false;
533 bool ok = true;
534 for (string_list::iterator i=dc.config_files.begin(); i!=dc.config_files.end(); i++) {
535 char *f = *i;
536 if (strcmp(f, fn) == 0) {
537 my_syslog("redundant or recursive include file detected");
538 ok = false;
539 break;
540 }
541 }
542 return ok;
524 } 543 }
525 544
526 545
527 //////////////////////////////////////////////// 546 ////////////////////////////////////////////////
528 // load a single config file 547 // load a single config file
529 // 548 //
549 static void load_conf_dcc(CONFIG &dc, char *name, char *fn);
550 static void load_conf_dcc(CONFIG &dc, char *name, char *fn) {
551 dc.config_files.push_back(fn);
552 char *list = BLACK;
553 const int LINE_SIZE = 2000;
554 ifstream is(fn);
555 if (is.fail()) return;
556 char line[LINE_SIZE];
557 char *delim = " \t";
558 int curline = 0;
559 while (!is.eof()) {
560 is.getline(line, LINE_SIZE);
561 curline++;
562 int n = strlen(line);
563 if (!n) continue;
564 for (int i=0; i<n; i++) line[i] = tolower(line[i]);
565 if (line[0] == '#') continue;
566 char *head = line;
567 if (strspn(line, delim) == 0) {
568 // have a leading ok/many tag to fetch
569 char *cmd = strtok(line, delim);
570 if (strcmp(cmd, MANY) == 0) list = BLACK;
571 else if (strcmp(cmd, OK) == 0) list = WHITE;
572 head = cmd + strlen(cmd) + 1;
573 }
574 char *cmd = strtok(head, delim);
575 if (!cmd) continue;
576 if (strcmp(cmd, "env_from") == 0) {
577 char *from = next_token(delim);
578 if (from) {
579 string_map &fm = really_find_from_map(dc, name);
580 fm[from] = list;
581 }
582 }
583 else if (strcmp(cmd, "env_to") == 0) {
584 char *to = next_token(delim);
585 if (to) {
586 dc.env_to_dnsbll[to] = list;
587 dc.env_to_chkfrom[to] = list;
588 }
589 }
590 else if (strcmp(cmd, "substitute") == 0) {
591 char *tag = next_token(delim);
592 if (tag && (strcmp(tag, "mail_host") == 0)) {
593 char *from = next_token(delim);
594 if (from) {
595 string_map &fm = really_find_from_map(dc, name);
596 fm[from] = list;
597 }
598 }
599 }
600 else if (strcmp(cmd, "include") == 0) {
601 char *fn = next_token(delim);
602 if (ok_to_include(dc, fn)) {
603 load_conf_dcc(dc, name, fn);
604 }
605 }
606
607 }
608 is.close();
609 }
610
611
530 static void load_conf(CONFIG &dc, char *fn); 612 static void load_conf(CONFIG &dc, char *fn);
531 static void load_conf(CONFIG &dc, char *fn) { 613 static void load_conf(CONFIG &dc, char *fn) {
532 dc.config_files.push_back(fn); 614 dc.config_files.push_back(fn);
533 map<char*, int, ltstr> commands; 615 map<char*, int, ltstr> commands;
534 enum {dummy, dnsbl, dnsbll, envfrom, envto, include}; 616 enum {dummy, dnsbl, dnsbll, envfrom, envto, include, includedcc};
535 commands["dnsbl" ] = dnsbl; 617 commands["dnsbl" ] = dnsbl;
536 commands["dnsbl_list"] = dnsbll; 618 commands["dnsbl_list" ] = dnsbll;
537 commands["env_from" ] = envfrom; 619 commands["env_from" ] = envfrom;
538 commands["env_to" ] = envto; 620 commands["env_to" ] = envto;
539 commands["include" ] = include; 621 commands["include" ] = include;
622 commands["include_dcc"] = includedcc;
540 const int LINE_SIZE = 2000; 623 const int LINE_SIZE = 2000;
541 ifstream is(fn); 624 ifstream is(fn);
542 if (is.fail()) return; 625 if (is.fail()) return;
543 char line[LINE_SIZE]; 626 char line[LINE_SIZE];
544 char orig[LINE_SIZE]; 627 char orig[LINE_SIZE];
634 processed = true; 717 processed = true;
635 } break; 718 } break;
636 719
637 case include: { 720 case include: {
638 char *fn = next_token(delim); 721 char *fn = next_token(delim);
639 if (fn) { 722 if (ok_to_include(dc, fn)) {
640 bool ok = true; 723 load_conf(dc, fn);
641 for (string_list::iterator i=dc.config_files.begin(); i!=dc.config_files.end(); i++) { 724 processed = true;
642 char *f = *i; 725 }
643 if (strcmp(f, fn) == 0) { 726 } break;
644 my_syslog("recursive include file detected"); 727
645 ok = false; 728 case includedcc: {
646 break; 729 char *name = next_token(delim);
647 } 730 if (!name) break;
648 } 731 char *fn = next_token(delim);
649 if (ok) { 732 if (ok_to_include(dc, fn)) {
650 load_conf(dc, fn); 733 load_conf_dcc(dc, name, fn);
651 processed = true; 734 processed = true;
652 }
653 } 735 }
654 } break; 736 } break;
655 737
656 default: { 738 default: {
657 } break; 739 } break;
708 // replace the global config pointer 790 // replace the global config pointer
709 pthread_mutex_lock(&config_mutex); 791 pthread_mutex_lock(&config_mutex);
710 CONFIG *old = config; 792 CONFIG *old = config;
711 config = newc; 793 config = newc;
712 pthread_mutex_unlock(&config_mutex); 794 pthread_mutex_unlock(&config_mutex);
713 // dumpit(env_from);
714 // dumpit("envelope to dnsbl", env_to_dnsbl);
715 // dumpit("envelope to check from", env_to_chkfrom);
716 // dumpit();
717 if (old) old_configs.insert(old); 795 if (old) old_configs.insert(old);
718 } 796 }
719 // now look for old configs with zero ref counts 797 // now look for old configs with zero ref counts
720 for (configp_set::iterator i=old_configs.begin(); i!=old_configs.end(); ) { 798 for (configp_set::iterator i=old_configs.begin(); i!=old_configs.end(); ) {
721 CONFIG *old = *i; 799 CONFIG *old = *i;
739 } 817 }
740 818
741 819
742 int main(int argc, char**argv) 820 int main(int argc, char**argv)
743 { 821 {
744 bool setconn = FALSE; 822 bool check = false;
823 bool setconn = false;
745 int c; 824 int c;
746 const char *args = "p:s:h"; 825 const char *args = "p:t:hc";
747 extern char *optarg; 826 extern char *optarg;
748 827
749 // Process command line options 828 // Process command line options
750 while ((c = getopt(argc, argv, args)) != -1) { 829 while ((c = getopt(argc, argv, args)) != -1) {
751 switch (c) { 830 switch (c) {
759 exit(EX_SOFTWARE); 838 exit(EX_SOFTWARE);
760 } 839 }
761 840
762 if (strncasecmp(optarg, "unix:", 5) == 0) unlink(optarg + 5); 841 if (strncasecmp(optarg, "unix:", 5) == 0) unlink(optarg + 5);
763 else if (strncasecmp(optarg, "local:", 6) == 0) unlink(optarg + 6); 842 else if (strncasecmp(optarg, "local:", 6) == 0) unlink(optarg + 6);
764 setconn = TRUE; 843 setconn = true;
765 break; 844 break;
766 845
767 case 't': 846 case 't':
768 if (optarg == NULL || *optarg == '\0') { 847 if (optarg == NULL || *optarg == '\0') {
769 fprintf(stderr, "Illegal timeout: %s\n", optarg); 848 fprintf(stderr, "Illegal timeout: %s\n", optarg);
773 fprintf(stderr, "smfi_settimeout failed\n"); 852 fprintf(stderr, "smfi_settimeout failed\n");
774 exit(EX_SOFTWARE); 853 exit(EX_SOFTWARE);
775 } 854 }
776 break; 855 break;
777 856
857 case 'c':
858 check = true;
859 break;
860
778 case 'h': 861 case 'h':
779 default: 862 default:
780 usage(argv[0]); 863 usage(argv[0]);
781 exit(EX_USAGE); 864 exit(EX_USAGE);
782 } 865 }
787 exit(EX_USAGE); 870 exit(EX_USAGE);
788 } 871 }
789 if (smfi_register(smfilter) == MI_FAILURE) { 872 if (smfi_register(smfilter) == MI_FAILURE) {
790 fprintf(stderr, "smfi_register failed\n"); 873 fprintf(stderr, "smfi_register failed\n");
791 exit(EX_UNAVAILABLE); 874 exit(EX_UNAVAILABLE);
875 }
876
877 if (check) {
878 CONFIG &dc = *new_conf();
879 dumpit(dc.env_from);
880 dumpit("envelope to (dnsbl list)", dc.env_to_dnsbll);
881 dumpit("envelope to (from map)", dc.env_to_chkfrom);
882 dumpit(dc);
883 return 0;
792 } 884 }
793 885
794 // switch to background mode 886 // switch to background mode
795 if (daemon(1,0) < 0) { 887 if (daemon(1,0) < 0) {
796 fprintf(stderr, "daemon() call failed\n"); 888 fprintf(stderr, "daemon() call failed\n");
819 if (f) { 911 if (f) {
820 fprintf(f, "-%d\n", (u_int)getpgrp()); 912 fprintf(f, "-%d\n", (u_int)getpgrp());
821 fclose(f); 913 fclose(f);
822 } 914 }
823 915
824 int rc = smfi_main(); 916 return smfi_main();
825 } 917 }