/* dnsbl.c - MessageWall DNS blacklist definitions Copyright (C) 2002 Ian Gulliver This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include "messagewall.h" #include "smtp.h" #include "dnsbl.h" static const char tagstring[] = "$Id: dnsbl.c,v 1.17 2002/07/11 03:07:50 ian Exp $"; int dnsbl_send_queries(int client) { struct messagewall_dnsbl_global_t *dnsbl; clients[client].resent_dnsbl = 0; dnsbl = dnsbl_head; while (dnsbl != NULL) { clients[client].dnsbl_fd[dnsbl->i] = firedns_dnsbl_lookup_a(&clients[client].ip,dnsbl->dnsbl.s); dnsbl = dnsbl->next; } return 0; } int dnsbl_resend_queries(int client) { struct messagewall_dnsbl_global_t *dnsbl; dnsbl = dnsbl_head; while (dnsbl != NULL) { if (clients[client].dnsbl_fd[dnsbl->i] < 0) { dnsbl = dnsbl->next; continue; } firedns_getresult(clients[client].dnsbl_fd[dnsbl->i]); clients[client].dnsbl_fd[dnsbl->i] = firedns_dnsbl_lookup_a(&clients[client].ip,dnsbl->dnsbl.s); dnsbl = dnsbl->next; } return 0; } int dnsbl_response(int client, int dnsbl) { char *ret; ret = firedns_getresult(clients[client].dnsbl_fd[dnsbl]); if (ret == NULL) clients[client].dnsbl_fd[dnsbl] = -1; else { clients[client].dnsbl_fd[dnsbl] = -2; /* * memcpy uses sizeof destination, is safe */ memcpy(&clients[client].dnsbl_ip[dnsbl],ret,sizeof(clients[client].dnsbl_ip[dnsbl])); /* ITS4: ignore memcpy */ } return 0; } int dnsbl_check_profile(int client, int force) { struct messagewall_dnsbl_profile_t *iter; iter = clients[client].profile->dnsbl; while (iter != NULL) { if (clients[client].dnsbl_fd[iter->global->i] == -2) { if (iter->have_response_ip == 1) if (memcmp(&clients[client].dnsbl_ip[iter->global->i],&iter->response_ip,sizeof(clients[client].dnsbl_ip[iter->global->i])) != 0) { iter = iter->next; continue; } if (force == 1) { if (smtp_reject(client,"DNSBL","%e/%s: IP is listed",SMTP_DNSBL,iter->score,0,&iter->global->dnsbl,firedns_ntoa4(&clients[client].ip)) == 1) return 1; } else return 1; } if (clients[client].dnsbl_fd[iter->global->i] >= 0) { if (force == 1) { iter = iter->next; continue; } else return -1; } iter = iter->next; } return 0; } int dnsbl_domain_send_queries(int client) { struct messagewall_dnsbl_global_t *dnsbl; static char buffer[512]; clients[client].resent_dnsbl_domain = 0; dnsbl = dnsbl_domain_head; while (dnsbl != NULL) { if (clients[client].dnsbl_domain_fd[dnsbl->i] >= 0) firedns_getresult(clients[client].dnsbl_domain_fd[dnsbl->i]); if (clients[client].fromdomain.l > 0) { firestring_snprintf(buffer,512,"%e.%e",&clients[client].fromdomain,&dnsbl->dnsbl); clients[client].dnsbl_domain_fd[dnsbl->i] = firedns_getip4(buffer); } else clients[client].dnsbl_domain_fd[dnsbl->i] = -1; dnsbl = dnsbl->next; } return 0; } int dnsbl_domain_resend_queries(int client) { struct messagewall_dnsbl_global_t *dnsbl; static char buffer[512]; if (clients[client].fromdomain.l == 0) return 0; dnsbl = dnsbl_domain_head; while (dnsbl != NULL) { if (clients[client].dnsbl_domain_fd[dnsbl->i] < 0) { dnsbl = dnsbl->next; continue; } firedns_getresult(clients[client].dnsbl_domain_fd[dnsbl->i]); firestring_snprintf(buffer,512,"%e.%e",&clients[client].fromdomain,&dnsbl->dnsbl); clients[client].dnsbl_domain_fd[dnsbl->i] = firedns_getip4(buffer); dnsbl = dnsbl->next; } return 0; } int dnsbl_domain_response(int client, int dnsbl) { char *ret; ret = firedns_getresult(clients[client].dnsbl_domain_fd[dnsbl]); if (ret == NULL) clients[client].dnsbl_domain_fd[dnsbl] = -1; else { clients[client].dnsbl_domain_fd[dnsbl] = -2; /* * memcpy uses sizeof destination, this is safe */ memcpy(&clients[client].dnsbl_domain_ip[dnsbl],ret,sizeof(clients[client].dnsbl_domain_ip[dnsbl])); /* ITS4: ignore memcpy */ } return 0; } int dnsbl_domain_check_profile(int client, int force) { struct messagewall_dnsbl_profile_t *iter; iter = clients[client].profile->dnsbl_domain; while (iter != NULL) { if (clients[client].dnsbl_domain_fd[iter->global->i] == -2) { if (iter->have_response_ip == 1) if (memcmp(&clients[client].dnsbl_domain_ip[iter->global->i],&iter->response_ip,sizeof(struct in_addr)) != 0) { iter = iter->next; continue; } if (force == 1) { if (smtp_reject(client,"DNSBL-DOMAIN","%e/%e: domain is listed by a domain-based DNS blacklist",SMTP_DNSBLDOMAIN,iter->score,0,&iter->global->dnsbl,&clients[client].fromdomain) == 1) return 1; } else return 1; } if (clients[client].dnsbl_domain_fd[iter->global->i] >= 0) { if (force == 1) { iter = iter->next; continue; } else return -1; } iter = iter->next; } return 0; }