ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/dnsbl.c
Revision: 5052
Committed: Mon Dec 22 11:56:03 2014 UTC (10 years, 8 months ago) by michael
Content type: text/x-csrc
File size: 7693 byte(s)
Log Message:
- Initial import of bopm 3.1.3

File Contents

# User Rev Content
1 michael 5052 /* vim: set shiftwidth=3 softtabstop=3 expandtab: */
2    
3     /*
4     Copyright (C) 2002-2003 Erik Fears
5    
6     This program is free software; you can redistribute it and/or
7     modify it under the terms of the GNU General Public License
8     as published by the Free Software Foundation; either version 2
9     of the License, or (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18    
19     Foundation, Inc.
20     59 Temple Place - Suite 330
21     Boston, MA 02111-1307, USA.
22    
23     */
24    
25     #include "setup.h"
26    
27     #include <stdio.h>
28    
29     #ifdef STDC_HEADERS
30     #include <stdlib.h>
31     #endif
32    
33     #include <string.h>
34     #include <sys/types.h>
35     #include <sys/socket.h>
36     #include <netinet/in.h>
37     #include <arpa/inet.h>
38     #include <time.h>
39     #include <errno.h>
40    
41     #include "compat.h"
42     #include "config.h"
43     #include "dnsbl.h"
44     #include "extern.h"
45     #include "list.h"
46     #include "log.h"
47     #include "malloc.h"
48     #include "scan.h"
49     #include "irc.h"
50     #include "stats.h"
51    
52     RCSID("$Id: dnsbl.c,v 1.30 2004/01/15 23:12:40 dg Exp $");
53    
54     /*
55     * Work out the DNSBL zones and send the dns query
56     */
57     void dnsbl_add(struct scan_struct *ss)
58     {
59     struct in_addr in;
60     unsigned char a, b, c, d;
61     char lookup[128];
62     node_t *p;
63     int res;
64     struct dnsbl_scan *ds;
65     struct BlacklistConf *bl;
66    
67     if (!inet_aton(ss->ip, &in))
68     {
69     log_printf("DNSBL -> Invalid address '%s', ignoring.", ss->ip);
70     return;
71     }
72    
73     d = (unsigned char) (in.s_addr >> 24) & 0xFF;
74     c = (unsigned char) (in.s_addr >> 16) & 0xFF;
75     b = (unsigned char) (in.s_addr >> 8) & 0xFF;
76     a = (unsigned char) in.s_addr & 0xFF;
77    
78     LIST_FOREACH(p, OpmItem->blacklists->head)
79     {
80     bl = p->data;
81    
82     #ifdef WORDS_BIGENDIAN
83     snprintf(lookup, 128, "%d.%d.%d.%d.%s", a, b, c, d, bl->name);
84     #else
85     snprintf(lookup, 128, "%d.%d.%d.%d.%s", d, c, b, a, bl->name);
86     #endif
87    
88     ds = MyMalloc(sizeof *ds);
89     ds->ss = ss;
90     ds->bl = bl;
91    
92     if(OPT_DEBUG)
93     log_printf("DNSBL -> Passed '%s' to resolver", lookup);
94    
95     res = firedns_getip(FDNS_QRY_A, lookup, (void *) ds);
96    
97     if(res == -1 && fdns_errno != FDNS_ERR_FDLIMIT)
98     {
99     log_printf("DNSBL -> Error sending dns lookup for '%s': %s", lookup, firedns_strerror(fdns_errno));
100     free(ds);
101     }
102     else
103     ss->scans++; /* Increase scan count - one for each blacklist */
104     }
105     }
106    
107     static void dnsbl_positive(struct scan_struct *ss, struct BlacklistConf *bl,
108     unsigned char type)
109     {
110     char text_type[128];
111     struct BlacklistReplyConf *item;
112     node_t *p;
113    
114     text_type[0] = '\0';
115    
116     if(bl->type == A_BITMASK)
117     {
118     LIST_FOREACH(p, bl->reply->head)
119     {
120     item = p->data;
121     if(item->number & type)
122     {
123     strncat(text_type, item->type, sizeof(text_type) - strlen(text_type) - 2);
124     text_type[sizeof(text_type) - 2] = '\0';
125     strncat(text_type, ", ", sizeof(text_type) - strlen(text_type) - 1);
126     text_type[sizeof(text_type) - 1] = '\0';
127     }
128     }
129     if(text_type[0] != '\0')
130     *(strrchr(text_type, ',')) = '\0';
131     }
132     else
133     {
134     LIST_FOREACH(p, bl->reply->head)
135     {
136     item = p->data;
137     if(item->number == type)
138     {
139     strncpy(text_type, item->type, sizeof(text_type));
140     break;
141     }
142     }
143     }
144    
145     if(text_type[0] == '\0' && bl->ban_unknown == 0)
146     {
147     if(OPT_DEBUG)
148     log_printf("DNSBL -> Unknown result from BL zone %s (%d)", bl->name, type);
149     return;
150     }
151    
152     if(ss->manual_target)
153     {
154     irc_send("PRIVMSG %s :CHECK -> DNSBL -> %s appears in BL zone %s (%s)",
155     ss->manual_target->name, ss->ip, bl->name, text_type);
156     }
157     else if(!ss->positive)
158     {
159     /* Only report it if no other scans have found positives yet. */
160     scan_positive(ss, (bl->kline[0] ? bl->kline : IRCItem->kline),
161     text_type);
162    
163     irc_send_channels("DNSBL -> %s!%s@%s appears in BL zone %s (%s)",
164     ss->irc_nick, ss->irc_username, ss->irc_hostname, bl->name,
165     text_type);
166     log_printf("DNSBL -> %s!%s@%s appears in BL zone %s (%s)",
167     ss->irc_nick, ss->irc_username, ss->irc_hostname, bl->name,
168     text_type);
169     }
170    
171     /* record stat */
172     stats_dnsblrecv(bl);
173     }
174    
175     void dnsbl_result(struct firedns_result *res)
176     {
177     struct dnsbl_scan *ds = res->info;
178    
179     if(OPT_DEBUG)
180     log_printf("DNSBL -> Lookup result for %s!%s@%s (%s) %d.%d.%d.%d (error: %d)",
181     ds->ss->irc_nick,
182     ds->ss->irc_username,
183     ds->ss->irc_hostname,
184     res->lookup,
185     (unsigned char)res->text[0],
186     (unsigned char)res->text[1],
187     (unsigned char)res->text[2],
188     (unsigned char)res->text[3], fdns_errno);
189    
190     /* Everything is OK */
191     if(res->text[0] == '\0' && fdns_errno == FDNS_ERR_NXDOMAIN)
192     {
193     if(ds->ss->manual_target != NULL)
194     irc_send("PRIVMSG %s :CHECK -> DNSBL -> %s does not appear in BL zone %s",
195     ds->ss->manual_target->name, ds->ss->ip,
196     (strlen(ds->ss->ip) < strlen(res->lookup))
197     ? (res->lookup + strlen(ds->ss->ip) + 1)
198     : res->lookup);
199    
200    
201     ds->ss->scans--; /* we are done with ss here */
202     scan_checkfinished(ds->ss); /* this could free ss, don't use ss after this point */
203     MyFree(ds); /* No longer need our information */
204     return;
205     }
206    
207     /* Either an error, or a positive lookup */
208    
209     if(fdns_errno == FDNS_ERR_NONE)
210     dnsbl_positive(ds->ss, ds->bl, (unsigned char)res->text[3]);
211     else
212     {
213     log_printf("DNSBL -> Lookup error on %s: %s", res->lookup,
214     firedns_strerror(fdns_errno));
215     if(fdns_errno != FDNS_ERR_TIMEOUT)
216     irc_send_channels("DNSBL -> Lookup error on %s: %s", res->lookup,
217     firedns_strerror(fdns_errno));
218     }
219    
220     /* Check if ss has any remaining scans */
221     ds->ss->scans--; /* We are done with ss here */
222     scan_checkfinished(ds->ss); /* this could free ss, don't use ss after this point */
223     MyFree(ds); /* Finished with dnsbl_scan too */
224     }
225    
226     void dnsbl_cycle(void)
227     {
228     firedns_cycle();
229     }
230    
231     /*
232     * Send an email to report this open proxy.
233     */
234    
235     void dnsbl_report(struct scan_struct *ss)
236     {
237     char buf[4096], cmdbuf[512];
238     FILE *fp;
239    
240     if(ss->ip == NULL)
241     return;
242    
243     if(strlen(OpmItem->dnsbl_to) == 0 || strlen(OpmItem->dnsbl_from) == 0 || strlen(OpmItem->sendmail) == 0)
244     return;
245    
246    
247     snprintf(cmdbuf, sizeof(cmdbuf), "%s -t", OpmItem->sendmail);
248     snprintf(buf, sizeof(buf),
249     "From: %s <%s>\n"
250     "To: %s\n"
251     "Subject: BOPM Report\n"
252     "X-BOPM-Version: %s\n\n"
253     "%s: %s:%d\n\n"
254     "%s\n", IRCItem->nick, OpmItem->dnsbl_from, OpmItem->dnsbl_to,
255     VERSION, scan_gettype(ss->remote->protocol), ss->ip,
256     ss->remote->port, ss->proof);
257    
258     if(OPT_DEBUG >= 3)
259     log_printf("DNSBL -> Sending following email:\n%s\n", buf);
260    
261     if ((fp = popen(cmdbuf, "w")) == NULL)
262     {
263     log_printf("DNSBL -> Failed to create pipe to '%s' for email report!", cmdbuf);
264     irc_send_channels("I was trying to create a pipe to'%s' to send a DNSBL "
265     "report, and it failed! I'll give up for now.",
266     cmdbuf);
267     return;
268     }
269    
270     fputs(buf, fp);
271     pclose(fp);
272    
273     log_printf("DNSBL -> Sent report to %s [%s]", OpmItem->dnsbl_to, ss->ip);
274     /* record send in stats */
275     stats_dnsblsend();
276     }