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

Comparing hopm/trunk/src/scan.c (file contents):
Revision 5091 by michael, Tue Dec 23 19:59:18 2014 UTC vs.
Revision 7818 by michael, Wed Oct 19 21:13:53 2016 UTC

# Line 1 | Line 1
1 /* vim: set shiftwidth=3 softtabstop=3 expandtab: */
2
1   /*
2 < * Copyright (C) 2002  Erik Fears
3 < *
6 < * This program is free software; you can redistribute it and/or
7 < * modify it under the terms of the GNU General Public License
8 < * as published by the Free Software Foundation; either version 2
9 < * of the License, or (at your option) any later version.
10 < *
11 < * This program is distributed in the hope that it will be useful,
12 < * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 < * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 < * GNU General Public License for more details.
15 < *
16 < * You should have received a copy of the GNU General Public License
17 < * along with this program; if not, write to
18 < *
19 < *       The Free Software Foundation, Inc.
20 < *       59 Temple Place - Suite 330
21 < *       Boston, MA  02111-1307, USA.
22 < *
2 > *  Copyright (c) 2002 Erik Fears
3 > *  Copyright (c) 2014-2016 ircd-hybrid development team
4   *
5 + *  This program is free software; you can redistribute it and/or modify
6 + *  it under the terms of the GNU General Public License as published by
7 + *  the Free Software Foundation; either version 2 of the License, or
8 + *  (at your option) any later version.
9 + *
10 + *  This program is distributed in the hope that it will be useful,
11 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 + *  GNU General Public License for more details.
14 + *
15 + *  You should have received a copy of the GNU General Public License
16 + *  along with this program; if not, write to the Free Software
17 + *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18 + *  USA
19   */
20  
21   #include "setup.h"
# Line 28 | Line 23
23   #include <stdio.h>
24   #include <unistd.h>
25   #include <assert.h>
26 <
27 < #ifdef STDC_HEADERS
28 < # include <stdlib.h>
29 < # include <string.h>
35 < #endif
36 <
37 < #ifdef TIME_WITH_SYS_TIME
38 < # include <sys/time.h>
39 < # include <time.h>
40 < #else
41 < # ifdef HAVE_SYS_TIME_H
42 < #  include <sys/time.h>
43 < # else
44 < #  include <time.h>
45 < # endif
46 < #endif
47 <
26 > #include <stdlib.h>
27 > #include <string.h>
28 > #include <sys/time.h>
29 > #include <time.h>
30   #include <errno.h>
31   #include <fcntl.h>
32 + #include <sys/socket.h>
33 + #include <netinet/in.h>
34 + #include <arpa/inet.h>
35  
51 #ifdef HAVE_SYS_POLL_H
52 # include <sys/poll.h>
53 #endif
54
55 #include "inet.h"
36   #include "compat.h"
37   #include "config.h"
38   #include "irc.h"
39   #include "log.h"
60 #include "opercmd.h"
40   #include "stats.h"
41   #include "dnsbl.h"
63 #include "extern.h"
42   #include "options.h"
43   #include "negcache.h"
44 < #include "malloc.h"
44 > #include "main.h"
45 > #include "memory.h"
46   #include "match.h"
47 + #include "misc.h"
48   #include "scan.h"
49  
50   /* Libopm */
# Line 77 | Line 57
57  
58   /* GLOBAL LISTS */
59  
60 < static list_t *SCANNERS = NULL;   /* List of OPM_T */
61 < static list_t *MASKS    = NULL;   /* Associative list of masks->scanners */
82 <
83 <
84 < /* Negative Cache */
85 < struct cnode *nc_head;
60 > static list_t *SCANNERS;  /* List of OPM_T */
61 > static list_t *MASKS;     /* Associative list of masks->scanners */
62  
63  
64   /* Function declarations */
65 <
66 < struct scan_struct *scan_create(char **, char *);
67 < void scan_free(struct scan_struct *);
68 < static void scan_irckline(struct scan_struct *, const char *, const char *);
93 < static void scan_negative(struct scan_struct *);
65 > static struct scan_struct *scan_create(const char *[], const char *);
66 > static void scan_free(struct scan_struct *);
67 > static void scan_irckline(const struct scan_struct *, const char *, const char *);
68 > static void scan_negative(const struct scan_struct *);
69   static void scan_log(OPM_REMOTE_T *);
70  
71   /** Callbacks for LIBOPM */
72 < void scan_open_proxy(OPM_T *, OPM_REMOTE_T *, int, void *);
73 < void scan_negotiation_failed(OPM_T *, OPM_REMOTE_T *, int, void *);
72 > static void scan_open_proxy(OPM_T *, OPM_REMOTE_T *, int, void *);
73 > static void scan_negotiation_failed(OPM_T *, OPM_REMOTE_T *, int, void *);
74   static void scan_timeout(OPM_T *, OPM_REMOTE_T *, int, void *);
75   static void scan_end(OPM_T *, OPM_REMOTE_T *, int, void *);
76   static void scan_handle_error(OPM_T *, OPM_REMOTE_T *, int, void *);
77  
78   extern FILE *scanlogfile;
79  
80 +
81   /* scan_cycle
82   *
83   *    Perform scanner tasks.
84   */
85 <
86 < void scan_cycle()
85 > void
86 > scan_cycle(void)
87   {
88 <   node_t *p;
113 <   struct scanner_struct *scs;
88 >  node_t *node;
89  
90 <   /* Cycle through the blacklist first.. */
91 <   dnsbl_cycle();
90 >  /* Cycle through the blacklist first.. */
91 >  dnsbl_cycle();
92  
93 <   /* Cycle each scanner object */
94 <   LIST_FOREACH(p, SCANNERS->head)
95 <   {
96 <      scs = p->data;
97 <      opm_cycle(scs->scanner);
98 <   }
93 >  /* Cycle each scanner object */
94 >  LIST_FOREACH(node, SCANNERS->head)
95 >  {
96 >    struct scanner_struct *scs = node->data;
97 >    opm_cycle(scs->scanner);
98 >  }
99   }
100  
126
127
128
101   /* scan_timer
102 < *  
102 > *
103   *    Perform actions that are to be performed every ~1 second.
104   *
105   * Parameters: NONE
106   * Return: NONE
107   *
108   */
109 < void scan_timer(void)
109 > void
110 > scan_timer(void)
111   {
112 <   static int nc_counter;
112 >  static time_t nc_counter;
113  
114 <   if (OptionsItem->negcache > 0)
115 <   {
116 <      if (nc_counter++ >= NEG_CACHE_REBUILD)
117 <      {
118 <         /*
119 <          * Time to rebuild the negative
120 <          * cache.
121 <          */
122 <         if(OPT_DEBUG)
123 <            log_printf("SCAN -> Rebuilding negative cache");
124 <
125 <         negcache_rebuild();
126 <         nc_counter = 0;
127 <      }
155 <   }
114 >  if (OptionsItem->negcache)
115 >  {
116 >    if (nc_counter++ >= OptionsItem->negcache_rebuild)
117 >    {
118 >      /*
119 >       * Time to rebuild the negative cache.
120 >       */
121 >      if (OPT_DEBUG)
122 >        log_printf("SCAN -> Rebuilding negative cache");
123 >
124 >      negcache_rebuild();
125 >      nc_counter = 0;
126 >    }
127 >  }
128   }
129  
158
130   /* scan_gettype(int protocol)
131   *
132   *    Return human readable name of OPM PROTOCOL given OPM_TYPE_PROTOCOL
# Line 168 | Line 139 | void scan_timer(void)
139   *    name
140   *
141   */
142 + const char *
143 + scan_gettype(int protocol)
144 + {
145 +  static const char *undef = "undefined";
146 +  static const struct protocol_assoc protocols[] =
147 +  {
148 +    { OPM_TYPE_HTTP,      "HTTP"      },
149 +    { OPM_TYPE_HTTPPOST,  "HTTPPOST"  },
150 +    { OPM_TYPE_SOCKS4,    "SOCKS4"    },
151 +    { OPM_TYPE_SOCKS5,    "SOCKS5"    },
152 +    { OPM_TYPE_WINGATE,   "WINGATE"   },
153 +    { OPM_TYPE_ROUTER,    "ROUTER"    },
154 +    { OPM_TYPE_HTTPS,     "HTTPS"     },
155 +    { OPM_TYPE_HTTPSPOST, "HTTPSPOST" },
156 +    { OPM_TYPE_DREAMBOX,  "DREAMBOX"  }
157 +  };
158 +
159 +  for (unsigned int i = 0; i < (sizeof(protocols) / sizeof(struct protocol_assoc)); ++i)
160 +    if (protocol == protocols[i].type)
161 +      return protocols[i].name;
162 +
163 +  return undef;
164 + }
165  
166 < const char *scan_gettype(int protocol)
166 > /* scan_checkexempt
167 > *
168 > *    Check mask against exempt list.
169 > *
170 > * Parameters:
171 > *     mask: Mask to check
172 > *
173 > * Return:
174 > *     1 if mask is in list
175 > *     0 if mask is not in list
176 > */
177 > static int
178 > scan_checkexempt(const char *mask, const char *ipmask)
179   {
180 <   unsigned int i;
175 <   static const char *undef = "undefined";
180 >  node_t *node;
181  
182 <   static struct protocol_assoc protocols[] =
183 <      {
184 <         { OPM_TYPE_HTTP,     "HTTP"     },
180 <         { OPM_TYPE_HTTPPOST, "HTTPPOST" },
181 <         { OPM_TYPE_SOCKS4,   "SOCKS4"   },
182 <         { OPM_TYPE_SOCKS5,   "SOCKS5"   },
183 <         { OPM_TYPE_WINGATE,  "WINGATE"  },
184 <         { OPM_TYPE_ROUTER,   "ROUTER"   }
185 <      };
186 <
187 <   for(i = 0; i < (sizeof(protocols) / sizeof(struct protocol_assoc)); i++)
188 <      if(protocol == protocols[i].type)
189 <         return protocols[i].name;
182 >  LIST_FOREACH(node, ExemptItem->masks->head)
183 >  {
184 >    const char *exempt_mask = node->data;
185  
186 <   return undef;
187 < }
186 >    if (!match(exempt_mask, mask) || !match(exempt_mask, ipmask))
187 >      return 1;
188 >  }
189  
190 +  return 0;
191 + }
192  
193   /* scan_init
194  
# Line 198 | Line 196 | const char *scan_gettype(int protocol)
196  
197     Parameters:
198        None
199 <  
199 >
200     Return:
201        None
202   */
203 <
204 < void scan_init()
203 > void
204 > scan_init(void)
205   {
206 <   node_t *p, *p2, *p3, *p4, *node;
207 <
208 <   struct UserConf *uc;
209 <   struct ScannerConf *sc;
210 <   struct ProtocolConf *pc;
211 <   struct scanner_struct *scs;
212 <
213 <   char *mask;
214 <   char *scannername;
215 <
216 <   /* FIXME: If rehash code is ever added, cleanup would need done here. */
217 <
218 <   SCANNERS = list_create();
219 <   MASKS    = list_create();
220 <
221 <   /* Setup each individual scanner */
222 <   LIST_FOREACH(p, ScannerItemList->head)
223 <   {
224 <      sc = p->data;
225 <      scs = MyMalloc(sizeof *scs);
226 <
227 <      if(OPT_DEBUG)
228 <         log_printf("SCAN -> Setting up scanner [%s]", sc->name);
229 <
230 <      /* Build the scanner */
231 <      scs->scanner = opm_create();
232 <      scs->name = (char *) DupString(sc->name);
233 <      scs->masks = list_create();
234 <
235 <      /* Setup configuration */
236 <      opm_config(scs->scanner, OPM_CONFIG_FD_LIMIT, &(sc->fd));
237 <      opm_config(scs->scanner, OPM_CONFIG_SCAN_IP, sc->target_ip);
238 <      opm_config(scs->scanner, OPM_CONFIG_SCAN_PORT, &(sc->target_port));
239 <      opm_config(scs->scanner, OPM_CONFIG_TIMEOUT, &(sc->timeout));
240 <      opm_config(scs->scanner, OPM_CONFIG_MAX_READ, &(sc->max_read));
241 <      opm_config(scs->scanner, OPM_CONFIG_BIND_IP, sc->vhost);
242 <
243 <      /* add target strings */
244 <      LIST_FOREACH(p2, sc->target_string->head)
245 <      opm_config(scs->scanner, OPM_CONFIG_TARGET_STRING, (char *) p2->data);
246 <
247 <      /* Setup callbacks */
248 <      opm_callback(scs->scanner, OPM_CALLBACK_OPENPROXY, &scan_open_proxy, scs);
249 <      opm_callback(scs->scanner, OPM_CALLBACK_NEGFAIL, &scan_negotiation_failed, scs);
250 <      opm_callback(scs->scanner, OPM_CALLBACK_TIMEOUT, &scan_timeout, scs);
251 <      opm_callback(scs->scanner, OPM_CALLBACK_END, &scan_end, scs);
252 <      opm_callback(scs->scanner, OPM_CALLBACK_ERROR, &scan_handle_error, scs);
253 <
254 <
255 <      /* Setup the protocols */
256 <      LIST_FOREACH(p2, sc->protocols->head)
257 <      {
258 <         pc = p2->data;
259 <
260 <         if(OPT_DEBUG >= 2)
261 <         {
262 <            log_printf("SCAN -> Adding protocol %s:%d to scanner [%s]",
263 <                  scan_gettype(pc->type), pc->port, scs->name);
264 <         }
265 <
266 <         if(opm_addtype(scs->scanner, pc->type, pc->port) == OPM_ERR_BADPROTOCOL)
267 <         {
268 <            log_printf("SCAN -> Error bad protocol %s:%d in scanner [%s]",
269 <                  scan_gettype(pc->type), pc->port, scs->name);
270 <         }
271 <      }
272 <
273 <      node = node_create(scs);
274 <      list_add(SCANNERS, node);
275 <   }
276 <
277 <
278 <   /* Give scanners a list of masks they scan */
279 <   LIST_FOREACH(p, SCANNERS->head)
280 <   {
281 <      scs = p->data;
282 <
283 <      LIST_FOREACH(p2, UserItemList->head)
284 <      {
285 <         uc = p2->data;
286 <         LIST_FOREACH(p3, uc->scanners->head)
287 <         {
288 <            scannername = p3->data;
289 <            /* Add all these masks to scanner */
290 <            if(strcasecmp(scannername, scs->name) == 0)
291 <            {
292 <               LIST_FOREACH(p4, uc->masks->head)
293 <               {
294 <                  mask = p4->data;
295 <
296 <                  if(OPT_DEBUG)
297 <                  {
298 <                     log_printf("SCAN -> Linking the mask [%s] to scanner "
299 <                           "[%s]", mask, scannername);
300 <                  }
301 <
302 <                  node = node_create(DupString(mask));
303 <                  list_add(scs->masks, node);
306 <               }
307 <               break;
308 <            }
309 <         }
310 <      }
311 <   }
206 >  node_t *p, *p2, *p3, *p4, *node;
207 >  struct UserConf *uc;
208 >  struct ScannerConf *sc;
209 >  struct ProtocolConf *pc;
210 >  struct scanner_struct *scs;
211 >
212 >  SCANNERS = list_create();
213 >  MASKS    = list_create();
214 >
215 >  /* Setup each individual scanner */
216 >  LIST_FOREACH(p, ScannerItemList->head)
217 >  {
218 >    sc = p->data;
219 >    scs = xcalloc(sizeof(*scs));
220 >
221 >    if (OPT_DEBUG)
222 >      log_printf("SCAN -> Setting up scanner [%s]", sc->name);
223 >
224 >    /* Build the scanner */
225 >    scs->scanner = opm_create();
226 >    scs->name = xstrdup(sc->name);
227 >    scs->masks = list_create();
228 >
229 >    /* Setup configuration */
230 >    opm_config(scs->scanner, OPM_CONFIG_FD_LIMIT, &sc->fd);
231 >    opm_config(scs->scanner, OPM_CONFIG_SCAN_IP, sc->target_ip);
232 >    opm_config(scs->scanner, OPM_CONFIG_SCAN_PORT, &sc->target_port);
233 >    opm_config(scs->scanner, OPM_CONFIG_TIMEOUT, &sc->timeout);
234 >    opm_config(scs->scanner, OPM_CONFIG_MAX_READ, &sc->max_read);
235 >    opm_config(scs->scanner, OPM_CONFIG_BIND_IP, sc->vhost);
236 >
237 >    /* add target strings */
238 >    LIST_FOREACH(p2, sc->target_string->head)
239 >      opm_config(scs->scanner, OPM_CONFIG_TARGET_STRING, p2->data);
240 >
241 >    /* Setup callbacks */
242 >    opm_callback(scs->scanner, OPM_CALLBACK_OPENPROXY, &scan_open_proxy, scs);
243 >    opm_callback(scs->scanner, OPM_CALLBACK_NEGFAIL, &scan_negotiation_failed, scs);
244 >    opm_callback(scs->scanner, OPM_CALLBACK_TIMEOUT, &scan_timeout, scs);
245 >    opm_callback(scs->scanner, OPM_CALLBACK_END, &scan_end, scs);
246 >    opm_callback(scs->scanner, OPM_CALLBACK_ERROR, &scan_handle_error, scs);
247 >
248 >    /* Setup the protocols */
249 >    LIST_FOREACH(p2, sc->protocols->head)
250 >    {
251 >      pc = p2->data;
252 >
253 >      if (OPT_DEBUG >= 2)
254 >        log_printf("SCAN -> Adding protocol %s:%d to scanner [%s]",
255 >                   scan_gettype(pc->type), pc->port, scs->name);
256 >
257 >      if (opm_addtype(scs->scanner, pc->type, pc->port) == OPM_ERR_BADPROTOCOL)
258 >        log_printf("SCAN -> Error bad protocol %s:%d in scanner [%s]",
259 >                    scan_gettype(pc->type), pc->port, scs->name);
260 >    }
261 >
262 >    node = node_create(scs);
263 >    list_add(SCANNERS, node);
264 >  }
265 >
266 >  /* Give scanners a list of masks they scan */
267 >  LIST_FOREACH(p, SCANNERS->head)
268 >  {
269 >    scs = p->data;
270 >
271 >    LIST_FOREACH(p2, UserItemList->head)
272 >    {
273 >      uc = p2->data;
274 >
275 >      LIST_FOREACH(p3, uc->scanners->head)
276 >      {
277 >        const char *scannername = p3->data;
278 >
279 >        /* Add all these masks to scanner */
280 >        if (strcasecmp(scannername, scs->name) == 0)
281 >        {
282 >          LIST_FOREACH(p4, uc->masks->head)
283 >          {
284 >            const char *mask = p4->data;
285 >
286 >            if (OPT_DEBUG)
287 >              log_printf("SCAN -> Linking the mask [%s] to scanner [%s]", mask, scannername);
288 >
289 >            node = node_create(xstrdup(mask));
290 >            list_add(scs->masks, node);
291 >          }
292 >
293 >          break;
294 >        }
295 >      }
296 >    }
297 >  }
298 >
299 >  /* Initialise negative cache */
300 >  if (OptionsItem->negcache)
301 >  {
302 >    if (OPT_DEBUG >= 2)
303 >      log_printf("SCAN -> Initializing negative cache");
304  
305 <   /* Initialise negative cache */
306 <   if (OptionsItem->negcache > 0)
315 <   {
316 <      if(OPT_DEBUG >= 2)
317 <         log_printf("SCAN -> Initializing negative cache");
318 <      nc_init(&nc_head);
319 <   }
305 >    negcache_init();
306 >  }
307   }
308  
322
309   /* scan_connect
310   *
311   *    scan_connect is called when m_notice (irc.c) matches a connection
# Line 335 | Line 321 | void scan_init()
321   * Return: NONE
322   *
323   */
324 <
325 < void scan_connect(char **user, char *msg)
324 > void
325 > scan_connect(const char *user[], const char *msg)
326   {
327 <
328 <   struct bopm_sockaddr ip;
329 <
330 <   node_t *p, *p2;
331 <   struct scan_struct *ss;
332 <   struct scanner_struct *scs;
333 <   char *scsmask;
334 <   int ret;
335 <
336 <   /*
337 <    * Have to use MSGLENMAX here because it is unknown what the max size of
338 <    * username/hostname can be.  Some ircds use really mad values for
339 <    * these.
340 <    */
341 <   static char mask[MSGLENMAX];
342 <   static char ipmask[MSGLENMAX];
343 <
344 <   /* Check negcache before anything */
345 <   if(OptionsItem->negcache > 0)
346 <   {
347 <      if (!inet_pton(AF_INET, user[3], &(ip.sa4.sin_addr)))
362 <      {
363 <         log_printf("SCAN -> Invalid IPv4 address '%s'!", user[3]);
364 <         return;
365 <      }
366 <      else
367 <      {
368 <         if(check_neg_cache(ip.sa4.sin_addr.s_addr) != NULL)
369 <         {
370 <            if(OPT_DEBUG)
371 <            {
372 <               log_printf("SCAN -> %s!%s@%s (%s) is negatively cached. "
373 <                     "Skipping all tests.", user[0], user[1], user[2],
374 <                     user[3]);
375 <            }
376 <            return;
377 <         }
378 <      }
379 <   }
380 <
381 <   /* Generate user mask */
382 <   snprintf(mask, MSGLENMAX, "%s!%s@%s", user[0], user[1], user[2]);
383 <   snprintf(ipmask, MSGLENMAX, "%s!%s@%s", user[0], user[1], user[3]);
384 <
385 <   /* Check exempt list now that we have a mask */
386 <   if(scan_checkexempt(mask, ipmask))
387 <   {
388 <      if(OPT_DEBUG)
389 <         log_printf("SCAN -> %s is exempt from scanning", mask);
327 >  node_t *p, *p2;
328 >  struct scan_struct *ss;
329 >  struct scanner_struct *scs;
330 >  int ret;
331 >
332 >  /*
333 >   * Have to use MSGLENMAX here because it is unknown what the max size of
334 >   * username/hostname can be.  Some ircds use really mad values for
335 >   * these.
336 >   */
337 >  char hostmask[MSGLENMAX];
338 >  char addrmask[MSGLENMAX];
339 >
340 >  /* Check negcache before anything */
341 >  if (OptionsItem->negcache)
342 >  {
343 >    if (check_neg_cache(user[3]))
344 >    {
345 >      if (OPT_DEBUG)
346 >        log_printf("SCAN -> %s!%s@%s (%s) is negatively cached. Skipping all tests.",
347 >                   user[0], user[1], user[2], user[3]);
348        return;
349 <   }
350 <
393 <   /* create scan_struct */
394 <   ss = scan_create(user, msg);
395 <
396 <   /* Store ss in the remote struct, so that in callbacks we have ss */
397 <   ss->remote->data = ss;
398 <
399 <   /* Start checking our DNSBLs */
400 <   if(LIST_SIZE(OpmItem->blacklists) > 0)
401 <      dnsbl_add(ss);
402 <
403 <   /* Add ss->remote to all matching scanners */
404 <   LIST_FOREACH(p, SCANNERS->head)
405 <   {
406 <      scs = p->data;
407 <      LIST_FOREACH(p2, scs->masks->head)
408 <      {
409 <         scsmask = p2->data;
410 <         if(!match(scsmask, mask))
411 <         {
412 <            if(OPT_DEBUG)
413 <            {
414 <               log_printf("SCAN -> Passing %s to scanner [%s]", mask,
415 <                     scs->name);
416 <            }
417 <
418 <            if((ret = opm_scan(scs->scanner, ss->remote)) != OPM_SUCCESS)
419 <            {
420 <               switch(ret)
421 <               {
422 <                  case OPM_ERR_NOPROTOCOLS:
423 <                     continue;
424 <                     break;
425 <                  case OPM_ERR_BADADDR:
426 <                     log_printf("OPM -> Bad address %s [%s].",
427 <                           (ss->manual_target ? ss->manual_target->name :
428 <                           "(unknown)"), ss->ip);
429 <                     break;
430 <                  default:
431 <                     log_printf("OPM -> Unknown error %s [%s].",
432 <                           (ss->manual_target ? ss->manual_target->name :
433 <                           "(unknown)"), ss->ip);
434 <                     break;
435 <               }
436 <            }
437 <            else
438 <               ss->scans++; /* Increase scan count only if OPM_SUCCESS */
349 >    }
350 >  }
351  
352 <            break; /* Continue to next scanner */
353 <         }
354 <      }
355 <   }
356 <
357 <   /* All scanners returned !OPM_SUCCESS and there were no dnsbl checks */
358 <   if(ss->scans == 0)
359 <      scan_free(ss);
352 >  /* Generate user mask */
353 >  snprintf(hostmask, sizeof(hostmask), "%s!%s@%s", user[0], user[1], user[2]);
354 >  snprintf(addrmask, sizeof(addrmask), "%s!%s@%s", user[0], user[1], user[3]);
355 >
356 >  /* Check exempt list now that we have a mask */
357 >  if (scan_checkexempt(hostmask, addrmask))
358 >  {
359 >    if (OPT_DEBUG)
360 >      log_printf("SCAN -> %s (%s) is exempt from scanning", hostmask, addrmask);
361 >
362 >    return;
363 >  }
364 >
365 >  /* Create scan_struct */
366 >  ss = scan_create(user, msg);
367 >
368 >  /* Store ss in the remote struct, so that in callbacks we have ss */
369 >  ss->remote->data = ss;
370 >
371 >  /* Start checking our DNSBLs */
372 >  if (LIST_SIZE(OpmItem->blacklists))
373 >    dnsbl_add(ss);
374 >
375 >  /* Add ss->remote to all matching scanners */
376 >  LIST_FOREACH(p, SCANNERS->head)
377 >  {
378 >    scs = p->data;
379 >
380 >    LIST_FOREACH(p2, scs->masks->head)
381 >    {
382 >      const char *scsmask = p2->data;
383 >
384 >      if (!match(scsmask, hostmask))
385 >      {
386 >        if (OPT_DEBUG)
387 >          log_printf("SCAN -> Passing %s to scanner [%s]", hostmask, scs->name);
388 >
389 >        if ((ret = opm_scan(scs->scanner, ss->remote)) != OPM_SUCCESS)
390 >        {
391 >          switch (ret)
392 >          {
393 >            case OPM_ERR_NOPROTOCOLS:
394 >              continue;
395 >              break;
396 >            case OPM_ERR_BADADDR:
397 >              log_printf("OPM -> Bad address %s [%s].",
398 >                         (ss->manual_target ? ss->manual_target->name :
399 >                         "(unknown)"), ss->ip);
400 >              break;
401 >            default:
402 >              log_printf("OPM -> Unknown error %s [%s].",
403 >                         (ss->manual_target ? ss->manual_target->name :
404 >                         "(unknown)"), ss->ip);
405 >              break;
406 >          }
407 >        }
408 >        else
409 >          ++ss->scans;  /* Increase scan count only if OPM_SUCCESS */
410 >
411 >        break;  /* Continue to next scanner */
412 >      }
413 >    }
414 >  }
415 >
416 >  /* All scanners returned !OPM_SUCCESS and there were no dnsbl checks */
417 >  if (ss->scans == 0)
418 >    scan_free(ss);
419   }
420  
450
451
452
421   /* scan_create
422   *
423 < *    Allocate scan struct, including user information and REMOTE
423 > *    Allocate scan struct, including user information and REMOTE
424   *    for LIBOPM.
425   *
426   * Parameters:
# Line 466 | Line 434 | void scan_connect(char **user, char *msg
434   * Return: Pointer to new scan_struct
435   *
436   */
437 <
438 < struct scan_struct *scan_create(char **user, char *msg)
437 > static struct scan_struct *
438 > scan_create(const char *user[], const char *msg)
439   {
440 <   struct scan_struct *ss;
473 <
474 <   ss = MyMalloc(sizeof *ss);
475 <
476 <   ss->irc_nick = (char *) DupString(user[0]);
477 <   ss->irc_username = (char *) DupString(user[1]);
478 <   ss->irc_hostname = (char *) DupString(user[2]);
479 <   ss->ip = (char *) DupString(user[3]);
480 <   ss->proof = (char *) DupString(msg);
481 <
482 <   ss->remote = opm_remote_create(ss->ip);
483 <   ss->scans = 0;
484 <   ss->positive = 0;
440 >  struct scan_struct *ss = xcalloc(sizeof(*ss));
441  
442 <   ss->manual_target = NULL;
442 >  ss->irc_nick = xstrdup(user[0]);
443 >  ss->irc_username = xstrdup(user[1]);
444 >  ss->irc_hostname = xstrdup(user[2]);
445 >  ss->ip = xstrdup(user[3]);
446 >  ss->proof = xstrdup(msg);
447 >  ss->remote = opm_remote_create(ss->ip);
448  
449 <   assert(ss->remote);
489 <   return ss;
449 >  return ss;
450   }
451  
492
493
494
452   /* scan_free
453   *
454   *    Free a scan_struct. This should only be done if the scan struct has
# Line 499 | Line 456 | struct scan_struct *scan_create(char **u
456   *
457   * Parameters:
458   *    ss: scan_struct to free
502 *
503 * Return: NONE
459   *
460 + * Return: NONE
461   */
462 <
463 < void scan_free(struct scan_struct *ss)
462 > static void
463 > scan_free(struct scan_struct *ss)
464   {
465 <   if(ss == NULL)
466 <      return;
467 <
468 <   MyFree(ss->irc_nick);
469 <   MyFree(ss->irc_username);
514 <   MyFree(ss->irc_hostname);
515 <   MyFree(ss->ip);
516 <   MyFree(ss->proof);
465 >  xfree(ss->irc_nick);
466 >  xfree(ss->irc_username);
467 >  xfree(ss->irc_hostname);
468 >  xfree(ss->ip);
469 >  xfree(ss->proof);
470  
471 <   opm_remote_free(ss->remote);
472 <   MyFree(ss);
471 >  opm_remote_free(ss->remote);
472 >  xfree(ss);
473   }
474  
522
523
475   /* scan_checkfinished
476   *
477   *   Check if a scan is complete (ss->scans <= 0)
478   *   and free it if need be.
528 *
479   */
480 <
481 < void scan_checkfinished(struct scan_struct *ss)
480 > void
481 > scan_checkfinished(struct scan_struct *ss)
482   {
483 <   if(ss->scans <= 0)
484 <   {
485 <
486 <      if(ss->manual_target != NULL)
537 <      {
538 <         irc_send("PRIVMSG %s :CHECK -> All tests on %s completed.",
483 >  if (ss->scans <= 0)
484 >  {
485 >    if (ss->manual_target)
486 >      irc_send("PRIVMSG %s :CHECK -> All tests on %s completed.",
487                 ss->manual_target->name, ss->ip);
488 <      }
489 <      else
490 <      {
491 <         if(OPT_DEBUG)
492 <         {
493 <            /* If there was a manual_target, then irc_nick, etc is NULL. */
494 <            log_printf("SCAN -> All tests on %s!%s@%s complete.",
495 <                  ss->irc_nick, ss->irc_username, ss->irc_hostname);
496 <         }
497 <
498 <         /* Scan was a negative */
551 <         if(!ss->positive)
552 <            scan_negative(ss);
553 <      }
488 >    else
489 >    {
490 >      if (OPT_DEBUG)
491 >        /* If there was a manual_target, then irc_nick, etc is NULL. */
492 >        log_printf("SCAN -> All tests on %s!%s@%s complete.",
493 >                   ss->irc_nick, ss->irc_username, ss->irc_hostname);
494 >
495 >      /* Scan was a negative */
496 >      if (ss->positive == 0)
497 >        scan_negative(ss);
498 >    }
499  
500 <      scan_free(ss);
501 <   }
500 >    scan_free(ss);
501 >  }
502   }
503  
559
560
504   /* scan_positive
505   *
506   *    Remote host (defined by ss) has been found positive by one or more
507   *    tests.
508   *
509   * Parameters:
510 < *    ss: scan_struct containing information regarding positive host
510 > *    ss: scan_struct containing information regarding positive host
511   *    kline: command to send to IRC server to ban the user (see scan_irckline)
512   *    type: string of the type of proxy found to be running on the host
513   *
514   * Return: NONE
515   *
516   */
517 <
518 < void scan_positive(struct scan_struct *ss, const char *kline, const char *type)
517 > void
518 > scan_positive(struct scan_struct *ss, const char *kline, const char *type)
519   {
520 <   node_t *node;
578 <   OPM_T *scanner;
579 <
580 <   /* If already a positive, don't kline/close again */
581 <   if(ss->positive)
582 <      return;
583 <
584 <   /* Format KLINE and send to IRC server */
585 <   scan_irckline(ss, kline, type);
520 >  node_t *node;
521  
522 <   /* Speed up the cleanup procedure */
523 <   /* Close all scans prematurely */
524 <   LIST_FOREACH(node, SCANNERS->head)
525 <   {
526 <      scanner = ((struct scanner_struct *)node->data)->scanner;
527 <      opm_end(scanner, ss->remote);
528 <   }
522 >  /* If already a positive, don't kline/close again */
523 >  if (ss->positive)
524 >    return;
525 >
526 >  /* Format KLINE and send to IRC server */
527 >  scan_irckline(ss, kline, type);
528 >
529 >  /* Speed up the cleanup procedure */
530 >  /* Close all scans prematurely */
531 >  LIST_FOREACH(node, SCANNERS->head)
532 >  {
533 >    OPM_T *scanner = ((struct scanner_struct *)node->data)->scanner;
534 >    opm_end(scanner, ss->remote);
535 >  }
536  
537 <   /* Set it as a positive (to avoid a scan_negative call later on */
538 <   ss->positive = 1;
537 >  /* Set it as a positive (to avoid a scan_negative call later on */
538 >  ss->positive = 1;
539   }
540  
599
600
541   /* scan_open_proxy CALLBACK
542   *
543   *    Called by libopm when a proxy is verified open.
# Line 607 | Line 547 | void scan_positive(struct scan_struct *s
547   *    remote: Remote struct containing information regarding remote end
548   *
549   * Return: NONE
610 *
550   */
551 <
552 < void scan_open_proxy(OPM_T *scanner, OPM_REMOTE_T *remote, int notused,
614 <      void *data)
551 > static void
552 > scan_open_proxy(OPM_T *scanner, OPM_REMOTE_T *remote, int notused, void *data)
553   {
554 <   struct scan_struct *ss;
555 <   struct scanner_struct *scs;
618 <
619 <   /* Record that a scan happened */
620 <   scan_log(remote);
554 >  struct scan_struct *ss;
555 >  struct scanner_struct *scs;
556  
557 <   scs = data;
558 <   ss = remote->data;
624 <
625 <   if(ss->manual_target == NULL)
626 <   {
627 <      /* kline and close scan */
628 <      scan_positive(ss, IRCItem->kline, scan_gettype(remote->protocol));
629 <
630 <      /* Report to blacklist */
631 <      dnsbl_report(ss);
632 <
633 <      irc_send_channels("OPEN PROXY -> %s!%s@%s %s:%d (%s) [%s]",
634 <            ss->irc_nick, ss->irc_username, ss->irc_hostname, remote->ip,
635 <            remote->port, scan_gettype(remote->protocol), scs->name);
636 <
637 <      log_printf("SCAN -> OPEN PROXY %s!%s@%s %s:%d (%s) [%s]",
638 <            ss->irc_nick, ss->irc_username, ss->irc_hostname, remote->ip,
639 <            remote->port, scan_gettype(remote->protocol), scs->name);
640 <   }
641 <   else
642 <   {
643 <      irc_send("PRIVMSG %s :CHECK -> OPEN PROXY %s:%d (%s) [%s]",
644 <            ss->manual_target->name, remote->ip, remote->port,
645 <            scan_gettype(remote->protocol), scs->name);
646 <
647 <      log_printf("SCAN -> OPEN PROXY %s:%d (%s) [%s]", remote->ip,
648 <            remote->port, scan_gettype(remote->protocol), scs->name);
649 <   }
557 >  /* Record that a scan happened */
558 >  scan_log(remote);
559  
560 +  scs = data;
561 +  ss = remote->data;
562 +
563 +  if (ss->manual_target == NULL)
564 +  {
565 +    /* kline and close scan */
566 +    scan_positive(ss, IRCItem->kline, scan_gettype(remote->protocol));
567 +
568 +    /* Report to blacklist */
569 +    dnsbl_report(ss);
570 +
571 +    irc_send_channels("OPEN PROXY -> %s!%s@%s %s:%d (%s) [%s]",
572 +                      ss->irc_nick, ss->irc_username, ss->irc_hostname, remote->ip,
573 +                      remote->port, scan_gettype(remote->protocol), scs->name);
574 +    log_printf("SCAN -> OPEN PROXY %s!%s@%s %s:%d (%s) [%s]",
575 +               ss->irc_nick, ss->irc_username, ss->irc_hostname, remote->ip,
576 +               remote->port, scan_gettype(remote->protocol), scs->name);
577 +  }
578 +  else
579 +  {
580 +    irc_send("PRIVMSG %s :CHECK -> OPEN PROXY %s:%d (%s) [%s]",
581 +             ss->manual_target->name, remote->ip, remote->port,
582 +             scan_gettype(remote->protocol), scs->name);
583 +    log_printf("SCAN -> OPEN PROXY %s:%d (%s) [%s]", remote->ip,
584 +               remote->port, scan_gettype(remote->protocol), scs->name);
585 +  }
586  
587 <   /* Record the proxy for stats purposes */
588 <   stats_openproxy(remote->protocol);
587 >  /* Record the proxy for stats purposes */
588 >  stats_openproxy(remote->protocol);
589   }
590  
656
657
658
591   /* scan_negotiation_failed CALLBACK
592   *
593   *    Called by libopm when negotiation of a specific protocol failed.
# Line 667 | Line 599 | void scan_open_proxy(OPM_T *scanner, OPM
599   * Return: NONE
600   *
601   */
602 <
603 < void scan_negotiation_failed(OPM_T *scanner, OPM_REMOTE_T *remote,
672 <      int notused, void *data)
602 > static void
603 > scan_negotiation_failed(OPM_T *scanner, OPM_REMOTE_T *remote, int notused, void *data)
604   {
605 < //   struct scan_struct *ss;
675 <   struct scanner_struct *scs;
676 <
677 <   /* Record that a scan happened */
678 <   scan_log(remote);
605 >  const struct scanner_struct *scs = data;
606  
607 <   scs = data;
608 < //   ss = remote->data;
607 >  /* Record that a scan happened */
608 >  scan_log(remote);
609  
610 <   if(OPT_DEBUG)
611 <   {
612 <      log_printf("SCAN -> Negotiation failed %s:%d (%s) [%s] (%d bytes read)",
613 <            remote->ip, remote->port, scan_gettype(remote->protocol),
687 <            scs->name, remote->bytes_read);
688 <   }
689 < /*
690 <   if(ss->manual_target != NULL)
691 <   {
692 <      irc_send("PRIVMSG %s :CHECK -> Negotiation failed %s:%d (%s) [%s] "
693 <            "(%d bytes read)", ss->manual_target->name, remote->ip,
694 <            remote->port, scan_gettype(remote->protocol), scs->name,
695 <            remote->bytes_read);
696 <   }
697 < */
610 >  if (OPT_DEBUG)
611 >    log_printf("SCAN -> Negotiation failed %s:%d (%s) [%s] (%d bytes read)",
612 >               remote->ip, remote->port, scan_gettype(remote->protocol), scs->name,
613 >               remote->bytes_read);
614   }
615  
700
701
616   /* scan_timeout CALLBACK
617   *
618   *    Called by libopm when the negotiation of a specific protocol timed out.
# Line 710 | Line 624 | void scan_negotiation_failed(OPM_T *scan
624   * Return: NONE
625   *
626   */
627 <
628 < static void scan_timeout(OPM_T *scanner, OPM_REMOTE_T *remote, int notused,
715 <      void *data)
627 > static void
628 > scan_timeout(OPM_T *scanner, OPM_REMOTE_T *remote, int notused, void *data)
629   {
630 < //   struct scan_struct *ss;
718 <   struct scanner_struct *scs;
719 <
720 <   /* Record that a scan happened */
721 <   scan_log(remote);
630 >  const struct scanner_struct *scs = data;
631  
632 <   scs = data;
633 < //   ss = remote->data;
632 >  /* Record that a scan happened */
633 >  scan_log(remote);
634  
635 <   if(OPT_DEBUG)
636 <   {
637 <      log_printf("SCAN -> Negotiation timed out %s:%d (%s) [%s] "
638 <            "(%d bytes read)", remote->ip, remote->port,
730 <            scan_gettype(remote->protocol), scs->name,
731 <            remote->bytes_read);
732 <   }
733 < /*
734 <   if(ss->manual_target != NULL)
735 <   {
736 <      irc_send("PRIVMSG %s :CHECK -> Negotiation timed out %s:%d (%s) [%s] "
737 <            "(%d bytes read)", ss->manual_target->name, remote->ip,
738 <            remote->port, scan_gettype(remote->protocol), scs->name,
739 <            remote->bytes_read);
740 <   }
741 < */
635 >  if (OPT_DEBUG)
636 >    log_printf("SCAN -> Negotiation timed out %s:%d (%s) [%s] (%d bytes read)",
637 >               remote->ip, remote->port, scan_gettype(remote->protocol), scs->name,
638 >               remote->bytes_read);
639   }
640  
744
745
641   /* scan_end CALLBACK
642   *
643   *    Called by libopm when a specific SCAN has completed (all protocols in
# Line 753 | Line 648 | static void scan_timeout(OPM_T *scanner,
648   *    remote: Remote struct containing information regarding remote end
649   *
650   * Return: NONE
756 *
651   */
652 <
653 < static void scan_end(OPM_T *scanner, OPM_REMOTE_T *remote, int notused,
760 <      void *data)
652 > static void
653 > scan_end(OPM_T *scanner, OPM_REMOTE_T *remote, int notused, void *data)
654   {
655 <   struct scan_struct *ss;
656 <   struct scanner_struct *scs;
655 >  struct scan_struct *ss;
656 >  struct scanner_struct *scs;
657  
658 <   scs = data;
659 <   ss = remote->data;
658 >  scs = data;
659 >  ss = remote->data;
660  
661 <   if(OPT_DEBUG)
662 <      log_printf("SCAN -> Scan %s [%s] completed", remote->ip, scs->name);
661 >  if (OPT_DEBUG)
662 >    log_printf("SCAN -> Scan %s [%s] completed", remote->ip, scs->name);
663  
664 <   ss->scans--;
665 <   scan_checkfinished(ss);
664 >  --ss->scans;
665 >  scan_checkfinished(ss);
666   }
667  
775
776
777
668   /* scan_handle_error CALLBACK
669   *
670   *    Called by libopm when an error occurs with a specific connection. This
# Line 786 | Line 676 | static void scan_end(OPM_T *scanner, OPM
676   *    err: OPM_ERROR code describing the error.
677   *
678   * Return: NONE
789 *
679   */
680 <
681 < static void scan_handle_error(OPM_T *scanner, OPM_REMOTE_T *remote,
793 <      int err, void *data)
680 > static void
681 > scan_handle_error(OPM_T *scanner, OPM_REMOTE_T *remote, int err, void *data)
682   {
683 +  struct scan_struct *ss;
684 +  struct scanner_struct *scs;
685  
686 <   struct scan_struct *ss;
687 <   struct scanner_struct *scs;
798 <
799 <   scs = data;
800 <   ss = remote->data;
686 >  scs = data;
687 >  ss = remote->data;
688  
689 <   switch(err)
690 <   {
691 <      case OPM_ERR_MAX_READ:
692 <         if(OPT_DEBUG >= 2)
693 <         {
694 <            log_printf("SCAN -> Max read on %s:%d (%s) [%s] (%d bytes read)",
695 <                  remote->ip, remote->port, scan_gettype(remote->protocol),
696 <                  scs->name, remote->bytes_read);
697 <         }
698 <  
699 <         if(ss->manual_target != NULL)
700 <         {
701 <            irc_send("PRIVMSG %s :CHECK -> Negotiation failed %s:%d (%s) "
702 <                  "[%s] (%d bytes read)", ss->manual_target->name,
703 <                  remote->ip, remote->port, scan_gettype(remote->protocol),
704 <                  scs->name, remote->bytes_read);
705 <         }
706 <         break;
707 <      case OPM_ERR_BIND:
708 <         log_printf("SCAN -> Bind error on %s:%d (%s) [%s]", remote->ip,
709 <               remote->port, scan_gettype(remote->protocol), scs->name);
710 <         break;
711 <      case OPM_ERR_NOFD:
712 <         log_printf("SCAN -> File descriptor allocation error %s:%d (%s) "
713 <               "[%s]", remote->ip, remote->port,
714 <               scan_gettype(remote->protocol), scs->name);
715 <        
716 <         if(ss->manual_target != NULL)
717 <         {
718 <            irc_send("PRIVMSG %s :CHECK -> Scan failed %s:%d (%s) [%s] "
719 <                  "(file descriptor allocation error)",
720 <                  ss->manual_target->name, remote->ip, remote->port,
721 <                  scan_gettype(remote->protocol), scs->name);
722 <         }
723 <         break;
837 <      default:   /* Unknown Error! */
838 <         if(OPT_DEBUG)
839 <         {
840 <            log_printf("SCAN -> Unknown error %s:%d (%s) [%s]", remote->ip,
841 <                  remote->port, scan_gettype(remote->protocol), scs->name);
842 <         }
843 <         break;
844 <   }
689 >  switch (err)
690 >  {
691 >    case OPM_ERR_MAX_READ:
692 >      if (OPT_DEBUG >= 2)
693 >        log_printf("SCAN -> Max read on %s:%d (%s) [%s] (%d bytes read)",
694 >                   remote->ip, remote->port, scan_gettype(remote->protocol),
695 >                   scs->name, remote->bytes_read);
696 >
697 >      if (ss->manual_target)
698 >        irc_send("PRIVMSG %s :CHECK -> Negotiation failed %s:%d (%s) "
699 >                 "[%s] (%d bytes read)", ss->manual_target->name,
700 >                 remote->ip, remote->port, scan_gettype(remote->protocol),
701 >                 scs->name, remote->bytes_read);
702 >      break;
703 >    case OPM_ERR_BIND:
704 >      log_printf("SCAN -> Bind error on %s:%d (%s) [%s]", remote->ip,
705 >                 remote->port, scan_gettype(remote->protocol), scs->name);
706 >      break;
707 >    case OPM_ERR_NOFD:
708 >      log_printf("SCAN -> File descriptor allocation error %s:%d (%s) "
709 >                "[%s]", remote->ip, remote->port,
710 >                scan_gettype(remote->protocol), scs->name);
711 >
712 >      if (ss->manual_target)
713 >        irc_send("PRIVMSG %s :CHECK -> Scan failed %s:%d (%s) [%s] "
714 >                 "(file descriptor allocation error)",
715 >                 ss->manual_target->name, remote->ip, remote->port,
716 >                 scan_gettype(remote->protocol), scs->name);
717 >      break;
718 >    default:  /* Unknown Error! */
719 >      if (OPT_DEBUG)
720 >        log_printf("SCAN -> Unknown error %s:%d (%s) [%s]", remote->ip,
721 >                   remote->port, scan_gettype(remote->protocol), scs->name);
722 >      break;
723 >  }
724   }
725  
847
848
849
726   /* scan_negative
727   *
728   *    Remote host (defined by ss) has passed all tests.
# Line 857 | Line 733 | static void scan_handle_error(OPM_T *sca
733   * Return: NONE
734   *
735   */
736 <
737 < static void scan_negative(struct scan_struct *ss)
736 > static void
737 > scan_negative(const struct scan_struct *ss)
738   {
739 <   /* Insert IP in negcache */
740 <   if(OptionsItem->negcache > 0)
741 <   {
742 <      if(OPT_DEBUG >= 2)
743 <         log_printf("SCAN -> Adding %s to negative cache", ss->ip);
868 <      negcache_insert(ss->ip);
869 <   }
870 < }
739 >  /* Insert IP in negcache */
740 >  if (OptionsItem->negcache)
741 >  {
742 >    if (OPT_DEBUG >= 2)
743 >      log_printf("SCAN -> Adding %s to negative cache", ss->ip);
744  
745 +    negcache_insert(ss->ip);
746 +  }
747 + }
748  
749   /* scan_irckline
750   *
751 < *    ss has been found as a positive host and is to be klined.
751 > *    ss has been found as a positive host and is to be klined.
752   *    Format a kline message using the kline message provided
753   *    as a format, then pass it to irc_send() to be sent to the remote server.
754   *
# Line 880 | Line 756 | static void scan_negative(struct scan_st
756   *    ss: scan_struct containing information regarding host to be klined
757   *    format: kline message to format
758   *    type: type of proxy found (%t format character)
883 *
884 * Return: NONE
759   *
760 + * Return: NONE
761   */
762 <
763 < static void scan_irckline(struct scan_struct *ss, const char *format, const char *type)
762 > static void
763 > scan_irckline(const struct scan_struct *ss, const char *format, const char *type)
764   {
765 +  char message[MSGLENMAX] = "";  /* OUTPUT */
766  
767 <   char message[MSGLENMAX];  /* OUTPUT */
768 <
769 <   unsigned short pos = 0;   /* position in format */
770 <   unsigned short len = 0;   /* position in message */
771 <   unsigned short size = 0;  /* temporary size buffer */
772 <
773 <   unsigned int i;
774 <
775 <   struct kline_format_assoc table[] =
776 <      {
777 <         {'i',   (void *) NULL,         FORMATTYPE_STRING },
778 <         {'h',   (void *) NULL,         FORMATTYPE_STRING },
779 <         {'u',   (void *) NULL,         FORMATTYPE_STRING },
780 <         {'n',   (void *) NULL,         FORMATTYPE_STRING },
781 <         {'t',   (void *) NULL,         FORMATTYPE_STRING }
782 <      };
783 <
784 <   table[0].data = ss->ip;
785 <   table[1].data = ss->irc_hostname;
786 <   table[2].data = ss->irc_username;
787 <   table[3].data = ss->irc_nick;
788 <   table[4].data = type;
789 <
790 <   /*
791 <    * Copy format to message character by character, inserting any matching
792 <    * data after %.
793 <    */
794 <   while(format[pos] != '\0' && len < (MSGLENMAX - 2))
795 <   {
796 <      switch(format[pos])
797 <      {
798 <
799 <         case '%':
800 <            /* % is the last char in the string, move on */
801 <            if(format[pos + 1] == '\0')
802 <               continue;
803 <
804 <            /* %% escapes % and becomes % */
805 <            if(format[pos + 1] == '%')
767 >  unsigned int pos = 0;   /* position in format */
768 >  unsigned int len = 0;   /* position in message */
769 >  unsigned int size = 0;  /* temporary size buffer */
770 >  struct kline_format_assoc
771 >  {
772 >    const char key;
773 >    const char *data;
774 >  } table[] =
775 >  {
776 >    { 'i',  ss->ip           },
777 >    { 'h',  ss->irc_hostname },
778 >    { 'u',  ss->irc_username },
779 >    { 'n',  ss->irc_nick     },
780 >    { 't',  type             },
781 >    { '\0', NULL             }
782 >  };
783 >
784 >  /*
785 >   * Copy format to message character by character, inserting any matching
786 >   * data after %.
787 >   */
788 >  while (format[pos] != '\0' && len < (MSGLENMAX - 2))
789 >  {
790 >    switch (format[pos])
791 >    {
792 >      case '%':
793 >        /* % is the last char in the string, move on */
794 >        if (format[pos + 1] == '\0')
795 >          continue;
796 >
797 >        /* %% escapes % and becomes % */
798 >        if (format[pos + 1] == '%')
799 >        {
800 >          message[len++] = '%';
801 >          ++pos;  /* Skip past the escaped % */
802 >          break;
803 >        }
804 >
805 >        /* Safe to check against table now */
806 >        for (const struct kline_format_assoc *tab = table; tab->key; ++tab)
807 >        {
808 >          if (tab->key == format[pos + 1])
809 >          {
810 >            size = strlen(tab->data);
811 >
812 >            /* Check if the new string can fit! */
813 >            if ((size + len) > (MSGLENMAX - 1))
814 >              break;
815 >            else
816              {
817 <               message[len++] = '%';
818 <               pos++; /* skip past the escaped % */
933 <               break;
817 >              strlcat(message, tab->data, sizeof(message));
818 >              len += size;
819              }
820 +          }
821 +        }
822  
823 <            /* Safe to check against table now */
824 <            for(i = 0; i < (sizeof(table) / sizeof(struct kline_format_assoc)); i++)
825 <            {
826 <               if(table[i].key == format[pos + 1])
827 <               {
828 <                  switch(table[i].type)
829 <                  {
830 <                     case FORMATTYPE_STRING:
831 <
832 <                        size = strlen(table[i].data);
833 <
834 <                        /* Check if the new string can fit! */
835 <                        if( (size + len) > (MSGLENMAX - 1) )
949 <                           break;
950 <                        else
951 <                        {
952 <                           strcat(message, table[i].data);
953 <                           len += size;
954 <                        }
955 <
956 <                     default:
957 <                        break;
958 <                  }
959 <               }
960 <            }
961 <            /* Skip key character */
962 <            pos++;
963 <            break;
964 <
965 <         default:
966 <            message[len++] = format[pos];
967 <            message[len] = '\0';
968 <            break;
969 <      }
970 <      /* continue to next character in format */
971 <      pos++;
972 <   }
973 <   irc_send("%s", message);
974 < }
823 >        /* Skip key character */
824 >        ++pos;
825 >        break;
826 >
827 >        default:
828 >          message[len++] = format[pos];
829 >          message[len] = '\0';
830 >          break;
831 >    }
832 >
833 >    /* Continue to next character in format */
834 >    ++pos;
835 >  }
836  
837 +  irc_send("%s", message);
838 + }
839  
840   /* scan_manual
841   *
842   *    Create a manual scan. A manual scan is a scan where the
843   *    scan_struct contains a manual_target pointer.
844   */
845 < void scan_manual(char *param, struct ChannelConf *target)
845 > void
846 > scan_manual(char *param, const struct ChannelConf *target)
847   {
848 <   struct in_addr *addr;
849 <   struct scan_struct *ss;
850 <   struct scanner_struct *scs;
851 <
852 <   char *ip;
853 <   char *scannername;
854 <
855 <   node_t *p;
856 <   int ret;
857 <
858 <   /* If there were no parameters sent, simply alert the user and return */
859 <   if(param == NULL)
860 <   {
861 <      irc_send("PRIVMSG %s :OPM -> Invalid parameters.", target->name);
862 <      return;
863 <   }
864 <
865 <   /* Try to extract a scanner name from param, otherwise we'll be
866 <      adding to all scanners */
867 <   ip = param;
868 <
869 <   if((scannername = strchr(param, ' ')) != NULL)
870 <   {
871 <      *scannername = '\0';
872 <      scannername++;
873 <   }
874 <
875 <   /* If IP is a hostname, resolve it using gethostbyname (which will block!) */
876 <   if (!(addr = firedns_resolveip4(ip)))
877 <   {
878 <       irc_send("PRIVMSG %s :CHECK -> Error resolving host '%s': %s",
879 <             target->name, ip, firedns_strerror(fdns_errno));
880 <       return;
881 <   }
882 <
883 <   /* IP = the resolved IP now (it was the ip OR hostname before) */
884 <   ip = inet_ntoa(*addr);
885 <
886 <   ss = MyMalloc(sizeof *ss);
887 <
888 <   /* These don't exist in a manual scan */
889 <   ss->irc_nick     = NULL;
890 <   ss->irc_username = NULL;
891 <   ss->irc_hostname = NULL;
892 <   ss->proof        = NULL;
893 <
894 <   ss->ip = DupString(ip);
895 <
896 <   ss->remote = opm_remote_create(ss->ip);
897 <   ss->remote->data = ss;
898 <   ss->scans = 0;
899 <   ss->positive = 0;
900 <
901 <   ss->manual_target = target;
902 <
903 <   assert(ss->remote);
904 <
905 <   if(scannername != NULL)
906 <   {
907 <      irc_send("PRIVMSG %s :CHECK -> Checking '%s' for open proxies [%s]",
908 <                target->name, ip,  scannername);
909 <   }
910 <   else
911 <   {
912 <      irc_send("PRIVMSG %s :CHECK -> Checking '%s' for open proxies on all "
913 <            "scanners", target->name, ip);
914 <   }
915 <
916 <   if(LIST_SIZE(OpmItem->blacklists) > 0)
917 <      dnsbl_add(ss);
918 <
919 <   /* Add ss->remote to all scanners */
920 <   LIST_FOREACH(p, SCANNERS->head)
921 <   {
922 <      scs = p->data;
923 <
924 <      /* If we have a scannername, only allow that scanner
925 <         to be used */
926 <      if(scannername != NULL)
927 <         if(strcasecmp(scannername, scs->name))
928 <            continue;
929 <
930 <      if(OPT_DEBUG)
931 <      {
932 <         log_printf("SCAN -> Passing %s to scanner [%s] (MANUAL SCAN)", ip,
933 <               scs->name);
934 <      }
935 <
936 <      if((ret = opm_scan(scs->scanner, ss->remote)) != OPM_SUCCESS)
937 <      {
938 <         switch(ret)
939 <         {
940 <            case OPM_ERR_NOPROTOCOLS:
941 <               break;
942 <            case OPM_ERR_BADADDR:
943 <               irc_send("PRIVMSG %s :OPM -> Bad address %s [%s]",
944 <                     ss->manual_target->name, ss->ip, scs->name);
945 <               break;
946 <            default:
947 <               irc_send("PRIVMSG %s :OPM -> Unknown error %s [%s]",
948 <                     ss->manual_target->name, ss->ip, scs->name);
949 <               break;
950 <         }
951 <      }
1088 <      else
1089 <         ss->scans++; /* Increase scan count only if OPM_SUCCESS */
1090 <   }
1091 <
1092 <   /* If all of the scanners gave !OPM_SUCCESS and there were no dnsbl checks,
1093 <      cleanup here */
1094 <   if(ss->scans == 0)
1095 <   {
1096 <      if(scannername != NULL)
1097 <      {
1098 <         irc_send("PRIVMSG %s :CHECK -> No such scanner '%s', or '%s' has "
848 >  char buf[INET6_ADDRSTRLEN];
849 >  const void *addr = NULL;
850 >  struct scan_struct *ss;
851 >  struct scanner_struct *scs;
852 >  const char *ip = NULL;
853 >  char *scannername;
854 >  node_t *node;
855 >  int ret;
856 >
857 >  /* If there were no parameters sent, simply alert the user and return */
858 >  if (param == NULL)
859 >  {
860 >    irc_send("PRIVMSG %s :OPM -> Invalid parameters.", target->name);
861 >    return;
862 >  }
863 >
864 >  /*
865 >   * Try to extract a scanner name from param, otherwise we'll be
866 >   * adding to all scanners
867 >   */
868 >  ip = param;
869 >
870 >  if ((scannername = strchr(param, ' ')))
871 >  {
872 >    *scannername = '\0';
873 >    scannername++;
874 >  }
875 >
876 >  /* If IP is a hostname, resolve it using gethostbyname (which will block!) */
877 >  if ((addr = firedns_resolveip4(ip)) == NULL)
878 >  {
879 >    irc_send("PRIVMSG %s :CHECK -> Error resolving host '%s': %s",
880 >             target->name, ip, firedns_strerror(firedns_errno));
881 >    return;
882 >  }
883 >
884 >  /* IP = the resolved IP now (it was the IP or hostname before) */
885 >  if ((ip = inet_ntop(AF_INET, addr, buf, sizeof(buf))) == NULL)
886 >  {
887 >    irc_send("PRIVMSG %s :CHECK -> invalid address: %s",
888 >             target->name, strerror(errno));
889 >    return;
890 >  }
891 >
892 >  ss = xcalloc(sizeof(*ss));
893 >  ss->ip = xstrdup(ip);
894 >  ss->remote = opm_remote_create(ss->ip);
895 >  ss->remote->data = ss;
896 >  ss->manual_target = target;
897 >
898 >  if (scannername)
899 >    irc_send("PRIVMSG %s :CHECK -> Checking '%s' for open proxies [%s]",
900 >             target->name, ip,  scannername);
901 >  else
902 >    irc_send("PRIVMSG %s :CHECK -> Checking '%s' for open proxies on all "
903 >             "scanners", target->name, ip);
904 >
905 >  if (LIST_SIZE(OpmItem->blacklists) > 0)
906 >    dnsbl_add(ss);
907 >
908 >  /* Add ss->remote to all scanners */
909 >  LIST_FOREACH(node, SCANNERS->head)
910 >  {
911 >    scs = node->data;
912 >
913 >    /*
914 >     * If we have a scannername, only allow that scanner
915 >     * to be used
916 >     */
917 >    if (scannername)
918 >      if (strcasecmp(scannername, scs->name))
919 >        continue;
920 >
921 >    if (OPT_DEBUG)
922 >      log_printf("SCAN -> Passing %s to scanner [%s] (MANUAL SCAN)", ip, scs->name);
923 >
924 >    if ((ret = opm_scan(scs->scanner, ss->remote)) != OPM_SUCCESS)
925 >    {
926 >      switch (ret)
927 >      {
928 >        case OPM_ERR_NOPROTOCOLS:
929 >          break;
930 >        case OPM_ERR_BADADDR:
931 >          irc_send("PRIVMSG %s :OPM -> Bad address %s [%s]",
932 >                   ss->manual_target->name, ss->ip, scs->name);
933 >          break;
934 >        default:
935 >          irc_send("PRIVMSG %s :OPM -> Unknown error %s [%s]",
936 >                   ss->manual_target->name, ss->ip, scs->name);
937 >          break;
938 >      }
939 >    }
940 >    else
941 >      ++ss->scans;  /* Increase scan count only if OPM_SUCCESS */
942 >  }
943 >
944 >  /*
945 >   * If all of the scanners gave !OPM_SUCCESS and there were no dnsbl checks,
946 >   * cleanup here
947 >   */
948 >  if (ss->scans == 0)
949 >  {
950 >    if (scannername)
951 >      irc_send("PRIVMSG %s :CHECK -> No such scanner '%s', or '%s' has "
952                 "0 protocols.", ss->manual_target->name, scannername,
953                 scannername);
1101      }
954  
955 <      irc_send("PRIVMSG %s :CHECK -> No scans active on '%s', aborting scan.",
956 <                ss->manual_target->name, ss->ip);
957 <      scan_free(ss);
958 <   }
955 >    irc_send("PRIVMSG %s :CHECK -> No scans active on '%s', aborting scan.",
956 >             ss->manual_target->name, ss->ip);
957 >    scan_free(ss);
958 >  }
959   }
960  
1109
1110
1111 /* scan_checkexempt
1112 *
1113 *    Check mask against exempt list.
1114 *
1115 * Parameters:
1116 *     mask: Mask to check
1117 *
1118 * Return:
1119 *     1 if mask is in list
1120 *     0 if mask is not in list
1121 */
1122
1123 int scan_checkexempt(char *mask, char *ipmask)
1124 {
1125   node_t *node;
1126   char *exempt_mask;
1127
1128   LIST_FOREACH(node, ExemptItem->masks->head)
1129   {
1130      exempt_mask = node->data;
1131      if(!match(exempt_mask, mask) || !match(exempt_mask, ipmask))
1132         return 1;
1133   }
1134
1135   return 0;
1136 }
1137
1138
961   /* scan_log
962   *
963   *    Log the fact that a given ip/port/protocol has just been scanned, if the
# Line 1144 | Line 966 | int scan_checkexempt(char *mask, char *i
966   * Parameters:
967   *     remote: OPM_REMOTE_T for the remote end
968   */
969 <
970 < static void scan_log(OPM_REMOTE_T *remote)
969 > static void
970 > scan_log(OPM_REMOTE_T *remote)
971   {
972 <   char buf_present[25];
1151 <   time_t present;
1152 <   struct tm *tm_present;
1153 <   struct scan_struct *ss = remote->data;
972 >  struct scan_struct *ss = remote->data;
973  
974 <   if(!(OptionsItem->scanlog && scanlogfile))
975 <      return;
974 >  if (!(OptionsItem->scanlog && scanlogfile))
975 >    return;
976  
977 <   time(&present);
978 <   tm_present = gmtime(&present);
979 <   strftime(buf_present, sizeof(buf_present), "%b %d %H:%M:%S %Y", tm_present);
1161 <
1162 <   fprintf(scanlogfile, "[%s] %s:%d (%s) \"%s\"\n", buf_present,
1163 <       remote->ip, remote->port, scan_gettype(remote->protocol), ss->proof);
1164 <   fflush(scanlogfile);
977 >  fprintf(scanlogfile, "[%s] %s:%d (%s) \"%s\"\n", date_iso8601(0), remote->ip,
978 >          remote->port, scan_gettype(remote->protocol), ss->proof);
979 >  fflush(scanlogfile);
980   }

Comparing hopm/trunk/src/scan.c (property svn:eol-style):
Revision 5091 by michael, Tue Dec 23 19:59:18 2014 UTC vs.
Revision 7818 by michael, Wed Oct 19 21:13:53 2016 UTC

# Line 0 | Line 1
1 + native

Comparing hopm/trunk/src/scan.c (property svn:keywords):
Revision 5091 by michael, Tue Dec 23 19:59:18 2014 UTC vs.
Revision 7818 by michael, Wed Oct 19 21:13:53 2016 UTC

# Line 0 | Line 1
1 + Id

Diff Legend

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