ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.0.x/src/dnsbl.c
Revision: 5171
Committed: Fri Dec 26 20:53:32 2014 UTC (9 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 7793 byte(s)
Log Message:
- Continue to use inet_pton() until we add full ipv6 support, but at least
  replace all occurrences of inet_aton() with inet_pton()

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

Properties

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