ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.0.x/src/dnsbl.c
Revision: 5206
Committed: Mon Dec 29 19:36:12 2014 UTC (9 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 7762 byte(s)
Log Message:
- Removed AC_HEADER_STDC configure test

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

Properties

Name Value
svn:eol-style native
svn:keywords Id