ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/dnsbl.c
Revision: 5279
Committed: Fri Jan 2 20:30:49 2015 UTC (11 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 7823 byte(s)
Log Message:
- Use 'const' and 'unsigned' whenever possible
- Removed pointless 0 assignments

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

Properties

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