ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/dnsbl.c
(Generate patch)

Comparing hopm/trunk/src/dnsbl.c (file contents):
Revision 5081 by michael, Mon Dec 22 19:16:10 2014 UTC vs.
Revision 5114 by michael, Wed Dec 24 22:12:05 2014 UTC

# Line 52 | Line 52 | along with this program; if not, write t
52   /*
53   * Work out the DNSBL zones and send the dns query
54   */
55 < void dnsbl_add(struct scan_struct *ss)
55 > void
56 > dnsbl_add(struct scan_struct *ss)
57   {
58 <   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 <   struct BlacklistConf *bl;
65 <
66 <   if (!inet_aton(ss->ip, &in))
67 <   {
68 <      log_printf("DNSBL -> Invalid address '%s', ignoring.", ss->ip);
69 <      return;
70 <   }
71 <
72 <   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 <
77 <   LIST_FOREACH(p, OpmItem->blacklists->head)
78 <   {
79 <                bl = p->data;
58 >  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 >
65 >
66 >  if (!inet_aton(ss->ip, &in))
67 >  {
68 >    log_printf("DNSBL -> Invalid address '%s', ignoring.", ss->ip);
69 >    return;
70 >  }
71 >
72 >  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 >
77 >  LIST_FOREACH(p, OpmItem->blacklists->head)
78 >  {
79 >    struct BlacklistConf *bl = p->data;
80  
81   #ifdef WORDS_BIGENDIAN
82 <      snprintf(lookup, 128, "%d.%d.%d.%d.%s", a, b, c, d, bl->name);
82 >    snprintf(lookup, 128, "%d.%d.%d.%d.%s", a, b, c, d, bl->name);
83   #else
84 <      snprintf(lookup, 128, "%d.%d.%d.%d.%s", d, c, b, a, bl->name);
84 >    snprintf(lookup, 128, "%d.%d.%d.%d.%s", d, c, b, a, bl->name);
85   #endif
86  
87 <      ds = MyMalloc(sizeof *ds);
88 <      ds->ss = ss;
89 <      ds->bl = bl;
87 >    ds = MyMalloc(sizeof *ds);
88 >    ds->ss = ss;
89 >    ds->bl = bl;
90 >
91 >    if (OPT_DEBUG)
92 >      log_printf("DNSBL -> Passed '%s' to resolver", lookup);
93 >
94 >    res = firedns_getip(FDNS_QRY_A, lookup, (void *) ds);
95 >
96 >    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 > }
105  
106 <      if(OPT_DEBUG)
107 <         log_printf("DNSBL -> Passed '%s' to resolver", lookup);
106 > static void
107 > dnsbl_positive(struct scan_struct *ss, struct BlacklistConf *bl, unsigned char type)
108 > {
109 >  char text_type[128] = "";
110 >  node_t *p;
111  
112 <      res = firedns_getip(FDNS_QRY_A, lookup, (void *) ds);
112 >  if (bl->type == A_BITMASK)
113 >  {
114 >    LIST_FOREACH(p, bl->reply->head)
115 >    {
116 >      struct BlacklistReplyConf *item = p->data;
117  
118 <      if(res == -1 && fdns_errno != FDNS_ERR_FDLIMIT)
118 >      if (item->number & type)
119        {
120 <         log_printf("DNSBL -> Error sending dns lookup for '%s': %s", lookup, firedns_strerror(fdns_errno));
121 <         free(ds);
99 <      }
100 <      else
101 <         ss->scans++; /* Increase scan count - one for each blacklist */
102 <   }
103 < }
120 >        strncat(text_type, item->type, sizeof(text_type) - strlen(text_type) - 2);
121 >        text_type[sizeof(text_type) - 2] = '\0';
122  
123 < static void dnsbl_positive(struct scan_struct *ss, struct BlacklistConf *bl,
124 <                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 <         }
123 >        strncat(text_type, ", ", sizeof(text_type) - strlen(text_type) - 1);
124 >        text_type[sizeof(text_type) - 1] = '\0';
125        }
126 <      if(text_type[0] != '\0')
127 <         *(strrchr(text_type, ',')) = '\0';
128 <   }
129 <   else
130 <   {
131 <      LIST_FOREACH(p, bl->reply->head)
126 >    }
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        {
139 <         item = p->data;
140 <         if(item->number == type)
136 <         {
137 <            strlcpy(text_type, item->type, sizeof(text_type));
138 <            break;
139 <         }
139 >        strlcpy(text_type, item->type, sizeof(text_type));
140 >        break;
141        }
142 <   }
143 <  
144 <   if(text_type[0] == '\0' && bl->ban_unknown == 0)
145 <   {
146 <      if(OPT_DEBUG)
147 <         log_printf("DNSBL -> Unknown result from BL zone %s (%d)", bl->name, type);
148 <      return;
149 <   }
150 <
151 <   if(ss->manual_target)
152 <   {
153 <      irc_send("PRIVMSG %s :CHECK -> DNSBL -> %s appears in BL zone %s (%s)",
154 <            ss->manual_target->name, ss->ip, bl->name, text_type);
155 <   }
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),
160 <            text_type);
161 <
162 <      irc_send_channels("DNSBL -> %s!%s@%s appears in BL zone %s (%s)",
163 <            ss->irc_nick, ss->irc_username, ss->irc_hostname, bl->name,
164 <            text_type);
165 <      log_printf("DNSBL -> %s!%s@%s appears in BL zone %s (%s)",
166 <            ss->irc_nick, ss->irc_username, ss->irc_hostname, bl->name,
167 <            text_type);
167 <   }
142 >    }
143 >  }
144 >
145 >  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 >
150 >    return;
151 >  }
152 >
153 >  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);
169 >  /* Record stat */
170 >  stats_dnsblrecv(bl);
171   }
172  
173 < void dnsbl_result(struct firedns_result *res)
173 > void
174 > dnsbl_result(struct firedns_result *res)
175   {
176 <        struct dnsbl_scan *ds = res->info;
176 >  struct dnsbl_scan *ds = res->info;
177  
178 <   if(OPT_DEBUG)
178 >  if (OPT_DEBUG)
179 >  {
180 >    if (ds->ss->manual_target)
181 >      log_printf("DNSBL -> Lookup result for %s (%s) %d.%d.%d.%d (error: %d)",
182 >                 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 >    else
189        log_printf("DNSBL -> Lookup result for %s!%s@%s (%s) %d.%d.%d.%d (error: %d)",
190 <          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 <   /* Everything is OK */
200 <   if(res->text[0] == '\0' && fdns_errno == FDNS_ERR_NXDOMAIN)
201 <   {
202 <      if(ds->ss->manual_target != NULL)
203 <         irc_send("PRIVMSG %s :CHECK -> DNSBL -> %s does not appear in BL zone %s",
204 <                   ds->ss->manual_target->name, ds->ss->ip,
205 <                    (strlen(ds->ss->ip) < strlen(res->lookup))
206 <                                                   ? (res->lookup + strlen(ds->ss->ip) + 1)
207 <                                                        : res->lookup);
208 <
209 <
210 <      ds->ss->scans--;            /* we are done with ss here */
211 <      scan_checkfinished(ds->ss); /* this could free ss, don't use ss after this point */
212 <                MyFree(ds);                   /* No longer need our information */
213 <      return;
214 <   }
215 <
216 <   /* Either an error, or a positive lookup */
217 <
218 <   if(fdns_errno == FDNS_ERR_NONE)
219 <      dnsbl_positive(ds->ss, ds->bl, (unsigned char)res->text[3]);
220 <   else
221 <        {
222 <      log_printf("DNSBL -> Lookup error on %s: %s", res->lookup,
223 <              firedns_strerror(fdns_errno));
224 <                if(fdns_errno != FDNS_ERR_TIMEOUT)
225 <                        irc_send_channels("DNSBL -> Lookup error on %s: %s", res->lookup,
226 <                                firedns_strerror(fdns_errno));
227 <        }
228 <
229 <   /* Check if ss has any remaining scans */
230 <   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 */
190 >                 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 >
200 >  /* 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 >
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 >  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 >
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)
233 > void
234 > dnsbl_cycle(void)
235   {
236 <   firedns_cycle();
236 >  firedns_cycle();
237   }
238  
239   /*
240   * Send an email to report this open proxy.
241   */
242 <
243 < void dnsbl_report(struct scan_struct *ss)
242 > void
243 > dnsbl_report(struct scan_struct *ss)
244   {
245 <   char buf[4096], cmdbuf[512];
246 <   FILE *fp;
245 >  char buf[4096], cmdbuf[512];
246 >  FILE *fp;
247 >
248 >  if (ss->ip == NULL)
249 >    return;
250 >
251 >  if (EmptyString(OpmItem->dnsbl_to) || EmptyString(OpmItem->dnsbl_from) || EmptyString(OpmItem->sendmail))
252 >    return;
253  
254 <   if(ss->ip == NULL)
255 <      return;
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 <   if (EmptyString(OpmItem->dnsbl_to) || EmptyString(OpmItem->dnsbl_from) || EmptyString(OpmItem->sendmail))
278 <      return;
277 >  fputs(buf, fp);
278 >  pclose(fp);
279  
280 +  log_printf("DNSBL -> Sent report to %s [%s]", OpmItem->dnsbl_to, ss->ip);
281  
282 <   snprintf(cmdbuf, sizeof(cmdbuf), "%s -t", OpmItem->sendmail);
283 <   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();
282 >  /* Record send in stats */
283 >  stats_dnsblsend();
284   }

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)