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()");