ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/dnsbl.c
Revision: 5081
Committed: Mon Dec 22 19:16:10 2014 UTC (9 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 7600 byte(s)
Log Message:
- Removed rcs tags

File Contents

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