ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/dnsbl.c
Revision: 5090
Committed: Tue Dec 23 19:10:33 2014 UTC (10 years, 8 months ago) by michael
Content type: text/x-csrc
File size: 7933 byte(s)
Log Message:
- dnsbl.c:dnsbl_result(): if we're processing a manual scan, don't show a n!u@h
  formatted string as ss->irc_nick, ss->irc_username, and ss->irc_hostname are
  NULL pointers anyway.

File Contents

# Content
1 /*
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 #include "match.h"
47 #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 strlcpy(text_type, item->type, sizeof(text_type));
138 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 if (ds->ss->manual_target)
179 log_printf("DNSBL -> Lookup result for %s (%s) %d.%d.%d.%d (error: %d)",
180 ds->ss->ip,
181 res->lookup,
182 (unsigned char)res->text[0],
183 (unsigned char)res->text[1],
184 (unsigned char)res->text[2],
185 (unsigned char)res->text[3], fdns_errno);
186 else
187 log_printf("DNSBL -> Lookup result for %s!%s@%s (%s) %d.%d.%d.%d (error: %d)",
188 ds->ss->irc_nick,
189 ds->ss->irc_username,
190 ds->ss->irc_hostname,
191 res->lookup,
192 (unsigned char)res->text[0],
193 (unsigned char)res->text[1],
194 (unsigned char)res->text[2],
195 (unsigned char)res->text[3], fdns_errno);
196
197 /* Everything is OK */
198 if(res->text[0] == '\0' && fdns_errno == FDNS_ERR_NXDOMAIN)
199 {
200 if(ds->ss->manual_target != NULL)
201 irc_send("PRIVMSG %s :CHECK -> DNSBL -> %s does not appear in BL zone %s",
202 ds->ss->manual_target->name, ds->ss->ip,
203 (strlen(ds->ss->ip) < strlen(res->lookup))
204 ? (res->lookup + strlen(ds->ss->ip) + 1)
205 : res->lookup);
206
207
208 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
214 /* Either an error, or a positive lookup */
215
216 if(fdns_errno == FDNS_ERR_NONE)
217 dnsbl_positive(ds->ss, ds->bl, (unsigned char)res->text[3]);
218 else
219 {
220 log_printf("DNSBL -> Lookup error on %s: %s", res->lookup,
221 firedns_strerror(fdns_errno));
222 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
227 /* 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 }
232
233 void dnsbl_cycle(void)
234 {
235 firedns_cycle();
236 }
237
238 /*
239 * Send an email to report this open proxy.
240 */
241
242 void dnsbl_report(struct scan_struct *ss)
243 {
244 char buf[4096], cmdbuf[512];
245 FILE *fp;
246
247 if(ss->ip == NULL)
248 return;
249
250 if (EmptyString(OpmItem->dnsbl_to) || EmptyString(OpmItem->dnsbl_from) || EmptyString(OpmItem->sendmail))
251 return;
252
253
254 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
265 if(OPT_DEBUG >= 3)
266 log_printf("DNSBL -> Sending following email:\n%s\n", buf);
267
268 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
277 fputs(buf, fp);
278 pclose(fp);
279
280 log_printf("DNSBL -> Sent report to %s [%s]", OpmItem->dnsbl_to, ss->ip);
281 /* record send in stats */
282 stats_dnsblsend();
283 }