Mercurial > dnsbl
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 } |