Mercurial > dnsbl
comparison src/dnsbl.cpp @ 90:962a1f8f1d9f stable-5-4
add verify statement to verify addresses with better mx host
author | carl |
---|---|
date | Sun, 18 Sep 2005 10:19:58 -0700 |
parents | 946fc1bcfb2c |
children | 505e77188317 |
comparison
equal
deleted
inserted
replaced
89:946fc1bcfb2c | 90:962a1f8f1d9f |
---|---|
14 milter or do anything with the socket. | 14 milter or do anything with the socket. |
15 -s Stress test by loading and deleting the current config in a loop. | 15 -s Stress test by loading and deleting the current config in a loop. |
16 -d increase debug level | 16 -d increase debug level |
17 -e f|t Print the results of looking up from address f and to address | 17 -e f|t Print the results of looking up from address f and to address |
18 t in the current config | 18 t in the current config |
19 | |
20 | |
21 TODO: | |
22 | |
23 1) Add option for using smtp connections to verify addresses from backup | |
24 mx machines. This allows the backup mx to learn the valid addresses | |
25 on the primary machine. | |
26 | 19 |
27 */ | 20 */ |
28 | 21 |
29 | 22 |
30 // from sendmail sample | 23 // from sendmail sample |
96 | 89 |
97 std::set<int> fd_pool; | 90 std::set<int> fd_pool; |
98 int NULL_SOCKET = -1; | 91 int NULL_SOCKET = -1; |
99 char *resolver_port = NULL; // unix domain socket to talk to the dns resolver process | 92 char *resolver_port = NULL; // unix domain socket to talk to the dns resolver process |
100 int resolver_socket = NULL_SOCKET; // socket used to listen for resolver requests | 93 int resolver_socket = NULL_SOCKET; // socket used to listen for resolver requests |
101 time_t ERROR_SOCKET_TIME = 60; // number of seconds between attempts to open the spam filter socket | 94 time_t ERROR_SOCKET_TIME = 60; // number of seconds between attempts to open a socket to the dns resolver process |
102 time_t last_error_time; | 95 time_t last_error_time; |
103 int resolver_sock_count = 0; // protected with fd_pool_mutex | 96 int resolver_sock_count = 0; // protected with fd_pool_mutex |
104 int resolver_pool_size = 0; // protected with fd_pool_mutex | 97 int resolver_pool_size = 0; // protected with fd_pool_mutex |
105 | 98 |
106 | 99 |
428 | 421 |
429 int maxq = sizeof(question); | 422 int maxq = sizeof(question); |
430 while (true) { | 423 while (true) { |
431 // read a question | 424 // read a question |
432 int rs = 0; | 425 int rs = 0; |
433 while (true) { | 426 while (rs < maxq) { |
434 int ns = read(socket, question+rs, maxq-rs); | 427 int ns = read(socket, question+rs, maxq-rs); |
435 if (ns > 0) { | 428 if (ns > 0) { |
436 rs += ns; | 429 rs += ns; |
437 if (question[rs-1] == '\0') { | 430 if (question[rs-1] == '\0') { |
438 // last byte read was the null terminator, we are done | 431 // last byte read was the null terminator, we are done |
445 shutdown(socket, SHUT_RDWR); | 438 shutdown(socket, SHUT_RDWR); |
446 close(socket); | 439 close(socket); |
447 return; | 440 return; |
448 } | 441 } |
449 } | 442 } |
443 question[rs-1] = '\0'; // ensure null termination | |
450 | 444 |
451 // find the answer | 445 // find the answer |
452 #ifdef NS_PACKETSZ | 446 #ifdef NS_PACKETSZ |
453 //char text[1000]; | 447 //char text[1000]; |
454 //snprintf(text, sizeof(text), "!!child worker process has a question %s", question); | 448 //snprintf(text, sizeof(text), "!!child worker process has a question %s", question); |
625 //////////////////////////////////////////////// | 619 //////////////////////////////////////////////// |
626 // check the dnsbls specified for this recipient | 620 // check the dnsbls specified for this recipient |
627 // | 621 // |
628 bool check_dnsbl(mlfiPriv &priv, dnsblp_list &dnsbll, DNSBLP &rejectlist); | 622 bool check_dnsbl(mlfiPriv &priv, dnsblp_list &dnsbll, DNSBLP &rejectlist); |
629 bool check_dnsbl(mlfiPriv &priv, dnsblp_list &dnsbll, DNSBLP &rejectlist) { | 623 bool check_dnsbl(mlfiPriv &priv, dnsblp_list &dnsbll, DNSBLP &rejectlist) { |
630 if (priv.authenticated) return false; | |
631 for (dnsblp_list::iterator i=dnsbll.begin(); i!=dnsbll.end(); i++) { | 624 for (dnsblp_list::iterator i=dnsbll.begin(); i!=dnsbll.end(); i++) { |
632 DNSBLP dp = *i; // non null by construction | 625 DNSBLP dp = *i; // non null by construction |
633 bool st; | 626 bool st; |
634 map<DNSBLP, bool>::iterator f = priv.checked.find(dp); | 627 map<DNSBLP, bool>::iterator f = priv.checked.find(dp); |
635 if (f == priv.checked.end()) { | 628 if (f == priv.checked.end()) { |
788 return SMFIS_CONTINUE; | 781 return SMFIS_CONTINUE; |
789 } | 782 } |
790 | 783 |
791 sfsistat mlfi_envfrom(SMFICTX *ctx, char **from) | 784 sfsistat mlfi_envfrom(SMFICTX *ctx, char **from) |
792 { | 785 { |
793 mlfiPriv &priv = *MLFIPRIV; | 786 mlfiPriv &priv = *MLFIPRIV; |
794 priv.mailaddr = to_lower_string(from[0]); | 787 priv.mailaddr = to_lower_string(from[0]); |
795 priv.authenticated = (smfi_getsymval(ctx, "{auth_authen}") != NULL); | 788 priv.authenticated = (smfi_getsymval(ctx, "{auth_authen}") != NULL); |
796 return SMFIS_CONTINUE; | 789 return SMFIS_CONTINUE; |
797 } | 790 } |
798 | 791 |
803 CONFIG &dc = *priv.pc; | 796 CONFIG &dc = *priv.pc; |
804 if (!priv.queueid) priv.queueid = strdup(smfi_getsymval(ctx, "i")); | 797 if (!priv.queueid) priv.queueid = strdup(smfi_getsymval(ctx, "i")); |
805 char *rcptaddr = rcpt[0]; | 798 char *rcptaddr = rcpt[0]; |
806 char *loto = to_lower_string(rcptaddr); | 799 char *loto = to_lower_string(rcptaddr); |
807 CONTEXT &con = *(dc.find_context(loto)->find_context(priv.mailaddr)); | 800 CONTEXT &con = *(dc.find_context(loto)->find_context(priv.mailaddr)); |
801 VERIFYP ver = con.find_verify(loto); | |
808 if (debug_syslog > 1) { | 802 if (debug_syslog > 1) { |
809 char buf[maxlen]; | 803 char buf[maxlen]; |
810 char msg[maxlen]; | 804 char msg[maxlen]; |
811 snprintf(msg, sizeof(msg), "from <%s> to <%s> using context %s", priv.mailaddr, loto, con.get_full_name(buf,maxlen)); | 805 snprintf(msg, sizeof(msg), "from <%s> to <%s> using context %s", priv.mailaddr, loto, con.get_full_name(buf,maxlen)); |
812 my_syslog(&priv, msg); | 806 my_syslog(&priv, msg); |
813 } | 807 } |
808 free(loto); | |
814 char *fromvalue = con.find_from(priv.mailaddr); | 809 char *fromvalue = con.find_from(priv.mailaddr); |
815 free(loto); | |
816 status st; | 810 status st; |
817 if (fromvalue == token_black) { | 811 if (priv.authenticated) { |
812 st = white; | |
813 } | |
814 else if (fromvalue == token_black) { | |
818 st = black; | 815 st = black; |
819 } | 816 } |
820 else if (fromvalue == token_white) { | 817 else if (fromvalue == token_white) { |
821 st = white; | 818 st = white; |
822 } | 819 } |
832 char buf[maxlen]; | 829 char buf[maxlen]; |
833 snprintf(buf, sizeof(buf), rejectlist->message, adr, adr); | 830 snprintf(buf, sizeof(buf), rejectlist->message, adr, adr); |
834 smfi_setreply(ctx, "550", "5.7.1", buf); | 831 smfi_setreply(ctx, "550", "5.7.1", buf); |
835 return SMFIS_REJECT; | 832 return SMFIS_REJECT; |
836 } | 833 } |
837 else if (st == black) { | 834 if (st == black) { |
838 // reject the recipient based on blacklisting either from or to | 835 // reject the recipient based on blacklisting either from or to |
839 smfi_setreply(ctx, "550", "5.7.1", "no such user"); | 836 smfi_setreply(ctx, "550", "5.7.1", "no such user"); |
840 return SMFIS_REJECT; | 837 return SMFIS_REJECT; |
841 } | 838 } |
842 else { | 839 if (ver && (st != white)) { |
843 // accept the recipient | 840 // try to verify this from/to pair of addresses since it is not explicitly whitelisted |
844 if (!con.get_content_filtering()) st = white; | 841 char *loto = to_lower_string(rcptaddr); |
845 if (st == oksofar) { | 842 bool rc = ver->ok(priv.mailaddr, loto); |
846 // but remember the non-whites | 843 free(loto); |
847 priv.need_content_filter(rcptaddr, con); | 844 if (!rc) { |
848 priv.only_whites = false; | 845 smfi_setreply(ctx, "550", "5.7.1", "no such user"); |
849 } | 846 return SMFIS_REJECT; |
850 if (st == white) { | 847 } |
851 priv.have_whites = true; | 848 } |
852 } | 849 // accept the recipient |
853 return SMFIS_CONTINUE; | 850 if (!con.get_content_filtering()) st = white; |
854 } | 851 if (st == oksofar) { |
852 // but remember the non-whites | |
853 priv.need_content_filter(rcptaddr, con); | |
854 priv.only_whites = false; | |
855 } | |
856 if (st == white) { | |
857 priv.have_whites = true; | |
858 } | |
859 return SMFIS_CONTINUE; | |
855 } | 860 } |
856 | 861 |
857 sfsistat mlfi_body(SMFICTX *ctx, u_char *data, size_t len) | 862 sfsistat mlfi_body(SMFICTX *ctx, u_char *data, size_t len) |
858 { | 863 { |
859 mlfiPriv &priv = *MLFIPRIV; | 864 mlfiPriv &priv = *MLFIPRIV; |
1053 fprintf(stderr, " inet:port@ip-address\n"); | 1058 fprintf(stderr, " inet:port@ip-address\n"); |
1054 fprintf(stderr, " local:local-domain-socket-file-name\n"); | 1059 fprintf(stderr, " local:local-domain-socket-file-name\n"); |
1055 fprintf(stderr, "-c will load and dump the config to stdout\n"); | 1060 fprintf(stderr, "-c will load and dump the config to stdout\n"); |
1056 fprintf(stderr, "-s will stress test the config loading code by repeating the load/free cycle\n"); | 1061 fprintf(stderr, "-s will stress test the config loading code by repeating the load/free cycle\n"); |
1057 fprintf(stderr, " in an infinte loop.\n"); | 1062 fprintf(stderr, " in an infinte loop.\n"); |
1058 fprintf(stderr, "-d will set the syslog message level, currently 0 to 3"); | 1063 fprintf(stderr, "-d will set the syslog message level, currently 0 to 3\n"); |
1059 fprintf(stderr, "-e will print the results of looking up the from and to addresses in the\n"); | 1064 fprintf(stderr, "-e will print the results of looking up the from and to addresses in the\n"); |
1060 fprintf(stderr, " current config. The | character is used to separate the from and to\n"); | 1065 fprintf(stderr, " current config. The | character is used to separate the from and to\n"); |
1061 fprintf(stderr, " addresses in the argument to the -e switch\n"); | 1066 fprintf(stderr, " addresses in the argument to the -e switch\n"); |
1062 } | 1067 } |
1063 | 1068 |
1356 pthread_t tid; | 1361 pthread_t tid; |
1357 if (pthread_create(&tid, 0, config_loader, 0)) | 1362 if (pthread_create(&tid, 0, config_loader, 0)) |
1358 my_syslog("failed to create config loader thread"); | 1363 my_syslog("failed to create config loader thread"); |
1359 if (pthread_detach(tid)) | 1364 if (pthread_detach(tid)) |
1360 my_syslog("failed to detach config loader thread"); | 1365 my_syslog("failed to detach config loader thread"); |
1366 if (pthread_create(&tid, 0, verify_closer, 0)) | |
1367 my_syslog("failed to create verify closer thread"); | |
1368 if (pthread_detach(tid)) | |
1369 my_syslog("failed to detach verify closer thread"); | |
1361 | 1370 |
1362 time_t starting = time(NULL); | 1371 time_t starting = time(NULL); |
1363 int rc = smfi_main(); | 1372 int rc = smfi_main(); |
1364 if ((rc != MI_SUCCESS) && (time(NULL) > starting+5*60)) { | 1373 if ((rc != MI_SUCCESS) && (time(NULL) > starting+5*60)) { |
1365 my_syslog("trying to restart after smfi_main()"); | 1374 my_syslog("trying to restart after smfi_main()"); |