1064 lines
34 KiB
C
1064 lines
34 KiB
C
/* NeoStats - IRC Statistical Services Copyright (c) 1999-2004 NeoStats Group Inc.
|
|
** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond
|
|
** http://www.neostats.net/
|
|
**
|
|
** This program is free software; you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation; either version 2 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program; if not, write to the Free Software
|
|
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
** USA
|
|
**
|
|
** NeoStats CVS Identification
|
|
** $Id$
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <fnmatch.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <arpa/nameser.h>
|
|
#include "neostats.h"
|
|
#include "opsb.h"
|
|
|
|
void reportdns(char *data, adns_answer *a);
|
|
void dnsblscan(char *data, adns_answer *a);
|
|
static int ScanNick(char **av, int ac);
|
|
int startscan(scaninfo *scandata);
|
|
void save_ports();
|
|
void unconf();
|
|
void save_exempts(exemptinfo *exempts);
|
|
|
|
char s_opsb[MAXNICK];
|
|
static ModUser *opsb_bot;
|
|
|
|
int online;
|
|
|
|
ModuleInfo __module_info = {
|
|
"OPSB",
|
|
"An Open Proxy Scanning Bot",
|
|
MODULE_VERSION,
|
|
__DATE__,
|
|
__TIME__
|
|
};
|
|
|
|
int findscan(const void *key1, const void *key2) {
|
|
const scaninfo *chan1 = key1;
|
|
return (strcasecmp(chan1->who, key2));
|
|
}
|
|
|
|
int ports_sort(const void *key1, const void *key2) {
|
|
port_list *pl1 = (port_list *)key1;
|
|
port_list *pl2 = (port_list *)key2;
|
|
if (pl1->type == pl2->type) {
|
|
if (pl1->port == pl2->port) {
|
|
return 0;
|
|
} else if (pl1->port > pl2->port) {
|
|
return 1;
|
|
} else {
|
|
return -1;
|
|
}
|
|
} else if (pl1->type > pl2->type) {
|
|
return 1;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int do_info(User *u, char **argv, int argc)
|
|
{
|
|
privmsg_list(u->nick, s_opsb, opsb_help_info);
|
|
return 0;
|
|
}
|
|
|
|
int do_lookup(User *u, char **argv, int argc)
|
|
{
|
|
lnode_t *lnode;
|
|
scaninfo *scandata;
|
|
int lookuptype;
|
|
|
|
scandata = malloc(sizeof(scaninfo));
|
|
scandata->dnsstate = REPORT_DNS;
|
|
strlcpy(scandata->who, u->nick, MAXNICK);
|
|
strlcpy(scandata->lookup, argv[2], MAXHOST);
|
|
/* if the lists are full, don't add it, and alert the user */
|
|
if (list_isfull(opsbl)) {
|
|
if (list_isfull(opsbq)) {
|
|
prefmsg(u->nick, s_opsb, "Too Busy. Try again Later");
|
|
free(scandata);
|
|
return 0;
|
|
}
|
|
prefmsg(u->nick, s_opsb, "OPSB list is full, queuing your request");
|
|
lnode = lnode_create(scandata);
|
|
list_append(opsbq, lnode);
|
|
}
|
|
if (inet_aton(scandata->lookup, NULL) > 0) {
|
|
lookuptype = adns_r_ptr;
|
|
} else {
|
|
if (argc == 4) {
|
|
if (!strcasecmp(argv[3], "txt"))
|
|
lookuptype = adns_r_txt;
|
|
else if (!strcasecmp(argv[3], "rp"))
|
|
lookuptype = adns_r_rp;
|
|
else if (!strcasecmp(argv[3], "ns"))
|
|
lookuptype = adns_r_ns;
|
|
else if (!strcasecmp(argv[3], "soa"))
|
|
lookuptype = adns_r_soa;
|
|
else
|
|
lookuptype = adns_r_a;
|
|
} else {
|
|
lookuptype = adns_r_a;
|
|
}
|
|
}
|
|
if (dns_lookup(scandata->lookup, lookuptype, reportdns, scandata->who) != 1) {
|
|
prefmsg(u->nick, s_opsb, "DnsLookup Failed.");
|
|
free(scandata);
|
|
return 0;
|
|
}
|
|
lnode = lnode_create(scandata);
|
|
list_append(opsbl, lnode);
|
|
return 0;
|
|
}
|
|
|
|
int do_remove(User *u, char **argv, int argc)
|
|
{
|
|
srakill_cmd(argv[2], "*");
|
|
chanalert(s_opsb, "%s attempted to remove an akill for *@%s", u->nick, argv[2]);
|
|
return 0;
|
|
}
|
|
|
|
int do_check(User *u, char **argv, int argc)
|
|
{
|
|
User *u2;
|
|
scaninfo *scandata;
|
|
|
|
if ((list_find(opsbl, argv[2], findscan)) || (list_find(opsbq, argv[2], findscan))) {
|
|
prefmsg(u->nick, s_opsb, "Already Scanning (or in queue) %s. Not Scanning again", argv[2]);
|
|
return 0;
|
|
}
|
|
scandata = malloc(sizeof(scaninfo));
|
|
scandata->doneban = 0;
|
|
scandata->u = u;
|
|
if ((u2 = finduser(argv[2])) != NULL) {
|
|
/* don't scan users from my server */
|
|
if (!strcasecmp(u2->server->name, me.name)) {
|
|
prefmsg(u->nick, s_opsb, "Error, Can not scan NeoStats Bots");
|
|
return -1;
|
|
}
|
|
strlcpy(scandata->who, u2->nick, MAXHOST);
|
|
strlcpy(scandata->lookup, u2->hostname, MAXHOST);
|
|
strlcpy(scandata->server, u2->server->name, MAXHOST);
|
|
scandata->ipaddr.s_addr = u2->ipaddr.s_addr;
|
|
if (scandata->ipaddr.s_addr > 0) {
|
|
scandata->dnsstate = DO_OPM_LOOKUP;
|
|
} else {
|
|
if (inet_aton(u2->hostname, &scandata->ipaddr) > 0)
|
|
scandata->dnsstate = DO_OPM_LOOKUP;
|
|
else {
|
|
scandata->dnsstate = GET_NICK_IP;
|
|
scandata->ipaddr.s_addr = 0;
|
|
}
|
|
}
|
|
} else {
|
|
strlcpy(scandata->who, argv[2], MAXHOST);
|
|
strlcpy(scandata->lookup, argv[2], MAXHOST);
|
|
bzero(scandata->server, MAXHOST);
|
|
if (inet_aton(argv[2], &scandata->ipaddr) > 0) {
|
|
scandata->dnsstate = DO_OPM_LOOKUP;
|
|
} else {
|
|
scandata->dnsstate = GET_NICK_IP;
|
|
scandata->ipaddr.s_addr = 0;
|
|
}
|
|
}
|
|
prefmsg(u->nick, s_opsb, "Checking %s for open Proxies", argv[2]);
|
|
if (!startscan(scandata))
|
|
prefmsg(u->nick, s_opsb, "Check Failed");
|
|
return 0;
|
|
}
|
|
|
|
int do_exclude(User *u, char **argv, int argc)
|
|
{
|
|
char *buf;
|
|
exemptinfo *exempts;
|
|
int i;
|
|
lnode_t *lnode;
|
|
|
|
if (!strcasecmp(argv[2], "LIST")) {
|
|
lnode = list_first(exempt);
|
|
i = 1;
|
|
prefmsg(u->nick, s_opsb, "Exception List:");
|
|
while (lnode) {
|
|
exempts = lnode_get(lnode);
|
|
prefmsg(u->nick, s_opsb, "%d) %s %s Added by %s for %s", i, exempts->host, (exempts->server ? "(Server)" : "(Client)"), exempts->who, exempts->reason);
|
|
++i;
|
|
lnode = list_next(exempt, lnode);
|
|
}
|
|
prefmsg(u->nick, s_opsb, "End of List.");
|
|
chanalert(s_opsb, "%s requested Exception List", u->nick);
|
|
} else if (!strcasecmp(argv[2], "ADD")) {
|
|
if (argc < 6) {
|
|
prefmsg(u->nick, s_opsb, "Syntax Error. /msg %s help exclude", s_opsb);
|
|
return 0;
|
|
}
|
|
if (list_isfull(exempt)) {
|
|
prefmsg(u->nick, s_opsb, "Error, Exception list is full");
|
|
return 0;
|
|
}
|
|
if (!index(argv[3], '.')) {
|
|
prefmsg(u->nick, s_opsb, "Host field does not contain a vaild host");
|
|
return 0;
|
|
}
|
|
exempts = malloc(sizeof(exemptinfo));
|
|
strlcpy(exempts->host, argv[3], MAXHOST);
|
|
if (atoi(argv[4]) > 0)
|
|
exempts->server = 1;
|
|
else
|
|
exempts->server = 0;
|
|
strlcpy(exempts->who, u->nick, MAXNICK);
|
|
buf = joinbuf(argv, argc, 5);
|
|
strlcpy(exempts->reason, buf, MAXHOST);
|
|
free(buf);
|
|
lnode = lnode_create(exempts);
|
|
list_append(exempt, lnode);
|
|
save_exempts(exempts);
|
|
|
|
prefmsg(u->nick, s_opsb, "Added %s (%s) exception to list", exempts->host, (exempts->server ? "(Server)" : "(Client)"));
|
|
chanalert(s_opsb, "%s added %s (%s) exception to list", u->nick, exempts->host, (exempts->server ? "(Server)" : "(Client)"));
|
|
} else if (!strcasecmp(argv[2], "DEL")) {
|
|
if (argc < 3) {
|
|
prefmsg(u->nick, s_opsb, "Syntax Error. /msg %s help exclude", s_opsb);
|
|
return 0;
|
|
}
|
|
if (atoi(argv[3]) != 0) {
|
|
lnode = list_first(exempt);
|
|
i = 1;
|
|
while (lnode) {
|
|
if (i == atoi(argv[3])) {
|
|
/* delete the entry */
|
|
exempts = lnode_get(lnode);
|
|
buf = malloc(BUFSIZE);
|
|
ircsnprintf(buf, BUFSIZE, "Exempt/%s", exempts->host);
|
|
DelConf(buf);
|
|
free(buf);
|
|
list_delete(exempt, lnode);
|
|
prefmsg(u->nick, s_opsb, "Deleted %s %s out of exception list", exempts->host, (exempts->server ? "(Server)" : "(Client)"));
|
|
chanalert(s_opsb, "%s deleted %s %s out of exception list", u->nick, exempts->host, (exempts->server ? "(Server)" : "(Client)"));
|
|
free(exempts);
|
|
return 1;
|
|
}
|
|
++i;
|
|
lnode = list_next(exempt, lnode);
|
|
}
|
|
/* if we get here, then we can't find the entry */
|
|
prefmsg(u->nick, s_opsb, "Error, Can't find entry %d. /msg %s exclude list", atoi(argv[3]), s_opsb);
|
|
return 0;
|
|
} else {
|
|
prefmsg(u->nick, s_opsb, "Error, Out of Range");
|
|
return 0;
|
|
}
|
|
} else {
|
|
prefmsg(u->nick, s_opsb, "Syntax Error. /msg %s help exclude", s_opsb);
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int do_ports(User *u, char **argv, int argc)
|
|
{
|
|
port_list *pl;
|
|
int i;
|
|
lnode_t *lnode;
|
|
|
|
if (!strcasecmp(argv[2], "LIST")) {
|
|
lnode = list_first(opsb.ports);
|
|
i = 1;
|
|
prefmsg(u->nick, s_opsb, "Port List:");
|
|
while (lnode) {
|
|
pl = lnode_get(lnode);
|
|
prefmsg(u->nick, s_opsb, "%d) %s Port: %d", i, type_of_proxy(pl->type), pl->port);
|
|
++i;
|
|
lnode = list_next(opsb.ports, lnode);
|
|
}
|
|
prefmsg(u->nick, s_opsb, "End of List.");
|
|
chanalert(s_opsb, "%s requested Port List", u->nick);
|
|
} else if (!strcasecmp(argv[2], "ADD")) {
|
|
if (argc < 5) {
|
|
prefmsg(u->nick, s_opsb, "Syntax Error. /msg %s help ports", s_opsb);
|
|
return 0;
|
|
}
|
|
if (list_isfull(opsb.ports)) {
|
|
prefmsg(u->nick, s_opsb, "Error, Ports list is full");
|
|
return 0;
|
|
}
|
|
if (!atoi(argv[4])) {
|
|
prefmsg(u->nick, s_opsb, "Port field does not contain a vaild port");
|
|
return 0;
|
|
}
|
|
if (get_proxy_by_name(argv[3]) < 1) {
|
|
prefmsg(u->nick, s_opsb, "Unknown Proxy type %s", argv[3]);
|
|
return 0;
|
|
}
|
|
/* check for duplicates */
|
|
lnode = list_first(opsb.ports);
|
|
while (lnode) {
|
|
pl = lnode_get(lnode);
|
|
if ((pl->type == get_proxy_by_name(argv[3])) && (pl->port == atoi(argv[4]))) {
|
|
prefmsg(u->nick, s_opsb, "Duplicate Entry for Protocol %s", argv[3]);
|
|
return 0;
|
|
}
|
|
lnode = list_next(opsb.ports, lnode);
|
|
}
|
|
pl = malloc(sizeof(port_list));
|
|
pl->type = get_proxy_by_name(argv[3]);
|
|
pl->port = atoi(argv[4]);
|
|
|
|
lnode = lnode_create(pl);
|
|
list_append(opsb.ports, lnode);
|
|
list_sort(opsb.ports, ports_sort);
|
|
save_ports();
|
|
add_port(pl->type, pl->port);
|
|
prefmsg(u->nick, s_opsb, "Added Port %d for Protocol %s to Ports list", pl->port, argv[3]);
|
|
chanalert(s_opsb, "%s added port %d for protocol %s to Ports list", u->nick, pl->port, argv[3]);
|
|
} else if (!strcasecmp(argv[2], "DEL")) {
|
|
if (argc < 3) {
|
|
prefmsg(u->nick, s_opsb, "Syntax Error. /msg %s help ports", s_opsb);
|
|
return 0;
|
|
}
|
|
if (atoi(argv[3]) != 0) {
|
|
lnode = list_first(opsb.ports);
|
|
i = 1;
|
|
while (lnode) {
|
|
if (i == atoi(argv[3])) {
|
|
/* delete the entry */
|
|
pl = lnode_get(lnode);
|
|
list_delete(opsb.ports, lnode);
|
|
prefmsg(u->nick, s_opsb, "Deleted Port %d of Protocol %s out of Ports list", pl->port, type_of_proxy(pl->type));
|
|
prefmsg(u->nick, s_opsb, "You need to Restart OPSB for the changes to take effect");
|
|
chanalert(s_opsb, "%s deleted port %d of Protocol %s out of Ports list", u->nick, pl->port, type_of_proxy(pl->type));
|
|
free(pl);
|
|
/* just to be sure, lets sort the list */
|
|
list_sort(opsb.ports, ports_sort);
|
|
save_ports();
|
|
return 1;
|
|
}
|
|
++i;
|
|
lnode = list_next(opsb.ports, lnode);
|
|
}
|
|
/* if we get here, then we can't find the entry */
|
|
prefmsg(u->nick, s_opsb, "Error, Can't find entry %d. /msg %s ports list", atoi(argv[3]), s_opsb);
|
|
return 0;
|
|
} else {
|
|
prefmsg(u->nick, s_opsb, "Error, Out of Range");
|
|
return 0;
|
|
}
|
|
} else {
|
|
prefmsg(u->nick, s_opsb, "Syntax Error. /msg %s help ports", s_opsb);
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int do_set_cb (User * u, char **av, int ac)
|
|
{
|
|
SetConf((void *)opsb.confed, CFGINT, "Confed");
|
|
del_mod_timer("Un_configured_warn");
|
|
return 0;
|
|
}
|
|
|
|
static bot_cmd opsb_commands[]=
|
|
{
|
|
{"INFO", do_info, 0, 0, opsb_help_info, opsb_help_info_oneline},
|
|
{"STATUS", do_status, 0, NS_ULEVEL_OPER, opsb_help_status, opsb_help_status_oneline},
|
|
{"LOOKUP", do_lookup, 1, NS_ULEVEL_OPER, opsb_help_lookup, opsb_help_lookup_oneline},
|
|
{"REMOVE", do_remove, 1, NS_ULEVEL_OPER, opsb_help_remove, opsb_help_remove_oneline},
|
|
{"CHECK", do_check, 1, NS_ULEVEL_OPER, opsb_help_check, opsb_help_check_oneline},
|
|
{"EXCLUDE", do_exclude, 1, NS_ULEVEL_ADMIN,opsb_help_exclude, opsb_help_exclude_oneline},
|
|
{"PORTS", do_ports, 1, NS_ULEVEL_ADMIN,opsb_help_ports, opsb_help_ports_oneline},
|
|
{NULL, NULL, 0, 0, NULL, NULL}
|
|
};
|
|
|
|
static bot_setting opsb_settings[]=
|
|
{
|
|
{"NICK", &s_opsb, SET_TYPE_NICK, 0, MAXNICK, NS_ULEVEL_ADMIN, "Nick", NULL, ns_help_set_nick, do_set_cb },
|
|
{"USER", &opsb.user, SET_TYPE_USER, 0, MAXUSER, NS_ULEVEL_ADMIN, "User", NULL, ns_help_set_user, do_set_cb },
|
|
{"HOST", &opsb.host, SET_TYPE_HOST, 0, MAXHOST, NS_ULEVEL_ADMIN, "Host", NULL, ns_help_set_host, do_set_cb },
|
|
{"REALNAME", &opsb.realname, SET_TYPE_REALNAME, 0, MAXREALNAME,NS_ULEVEL_ADMIN, "RealName", NULL, ns_help_set_realname, do_set_cb },
|
|
{"DISABLESCAN", &opsb.doscan, SET_TYPE_BOOLEAN, 0, 0, NS_ULEVEL_ADMIN, "DoScan", NULL, opsb_help_set_disablescan, do_set_cb },
|
|
{"DOBAN", &opsb.doban, SET_TYPE_BOOLEAN, 0, 0, NS_ULEVEL_ADMIN, "DoBan", NULL, opsb_help_set_doban, do_set_cb },
|
|
{"TARGETIP", &opsb.targethost, SET_TYPE_IPV4, 0, MAXHOST, NS_ULEVEL_ADMIN, "TargetHost", NULL, opsb_help_set_targetip, do_set_cb },
|
|
{"TARGETPORT", &opsb.targetport, SET_TYPE_INT, 0, 0, NS_ULEVEL_ADMIN, "TargetPort", NULL, opsb_help_set_targetport, do_set_cb },
|
|
{"OPMDOMAIN", &opsb.opmdomain, SET_TYPE_HOST, 0, MAXHOST, NS_ULEVEL_ADMIN, "OpmDomain", NULL, opsb_help_set_opmdomain, do_set_cb },
|
|
{"MAXBYTES", &opsb.maxbytes, SET_TYPE_INT, 0, 0, NS_ULEVEL_ADMIN, "MaxBytes", NULL, opsb_help_set_maxbytes, do_set_cb },
|
|
{"TIMEOUT", &opsb.timeout, SET_TYPE_INT, 0, 120, NS_ULEVEL_ADMIN, "TimeOut", NULL, opsb_help_set_timeout, do_set_cb },
|
|
{"OPENSTRING", &opsb.lookforstring,SET_TYPE_MSG, 0, BUFSIZE, NS_ULEVEL_ADMIN, "TriggerString",NULL, opsb_help_set_openstring, do_set_cb },
|
|
{"SPLITTIME", &opsb.timedif, SET_TYPE_INT, 0, 0, NS_ULEVEL_ADMIN, "SplitTime", NULL, opsb_help_set_splittime, do_set_cb },
|
|
{"SCANMSG", &opsb.scanmsg, SET_TYPE_MSG, 0, BUFSIZE, NS_ULEVEL_ADMIN, "ScanMsg", NULL, opsb_help_set_scanmsg, do_set_cb },
|
|
{"BANTIME", &opsb.bantime, SET_TYPE_INT, 0, 0, NS_ULEVEL_ADMIN, "BanTime", NULL, opsb_help_set_bantime, do_set_cb },
|
|
{"CACHETIME", &opsb.cachetime, SET_TYPE_INT, 0, 0, NS_ULEVEL_ADMIN, "CacheTime", NULL, opsb_help_set_cachetime, do_set_cb },
|
|
{"VERBOSE", &opsb.verbose, SET_TYPE_BOOLEAN, 0, 0, NS_ULEVEL_ADMIN, "Verbose", NULL, opsb_help_set_verbose, do_set_cb },
|
|
{NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL },
|
|
};
|
|
|
|
static int Online(char **av, int ac) {
|
|
struct sockaddr_in sa;
|
|
socklen_t ulen = sizeof(struct sockaddr_in);
|
|
|
|
SET_SEGV_LOCATION();
|
|
|
|
opsb_bot = init_mod_bot(s_opsb, opsb.user, opsb.host, opsb.realname, services_bot_modes,
|
|
BOT_FLAG_RESTRICT_OPERS|BOT_FLAG_DEAF, opsb_commands, opsb_settings, __module_info.module_name);
|
|
|
|
if (opsb.confed == 0) {
|
|
add_mod_timer("unconf", "Un_configured_warn", "opsb", 60);
|
|
unconf();
|
|
getpeername(servsock, (struct sockaddr *)&sa, (socklen_t*)&ulen);
|
|
strlcpy(opsb.targethost, inet_ntoa(sa.sin_addr), MAXHOST);
|
|
}
|
|
if(opsb.verbose) {
|
|
if (opsb.doscan) {
|
|
chanalert(s_opsb, "Open Proxy Scanning bot has started (Concurrent Scans: %d Sockets %d)", opsb.socks, opsb.socks *7);
|
|
} else {
|
|
chanalert(s_opsb, "DNS Blacklist Lookup is only Enabled!! (No Open Proxy Scans)");
|
|
}
|
|
}
|
|
online = 1;
|
|
return 1;
|
|
}
|
|
|
|
void unconf() {
|
|
if (opsb.confed == 1) return;
|
|
chanalert(s_opsb, "Warning, OPSB is configured with default Settings. Please Update this ASAP");
|
|
globops(s_opsb, "Warning, OPSB is configured with default Settings, Please Update this ASAP");
|
|
}
|
|
|
|
void save_ports() {
|
|
lnode_t *pn;
|
|
port_list *pl;
|
|
char confpath[CONFBUFSIZE];
|
|
char ports[CONFBUFSIZE];
|
|
char tmpports[CONFBUFSIZE];
|
|
int lasttype = -1;
|
|
pn = list_first(opsb.ports);
|
|
while (pn) {
|
|
pl = lnode_get(pn);
|
|
/* if the port is different from the last round, and its not the first round, save it */
|
|
if ((pl->type != lasttype) && (lasttype != -1)) {
|
|
strlcpy(confpath, type_of_proxy(lasttype), CONFBUFSIZE);
|
|
SetConf((void *)ports, CFGSTR, confpath);
|
|
}
|
|
if (pl->type != lasttype) {
|
|
ircsnprintf(ports, CONFBUFSIZE, "%d", pl->port);
|
|
} else {
|
|
ircsnprintf(tmpports, CONFBUFSIZE, "%s %d", ports, pl->port);
|
|
strlcpy(ports, tmpports, CONFBUFSIZE);
|
|
}
|
|
lasttype = pl->type;
|
|
pn = list_next(opsb.ports, pn);
|
|
}
|
|
strlcpy(confpath, type_of_proxy(lasttype), CONFBUFSIZE);
|
|
SetConf((void *)ports, CFGSTR, confpath);
|
|
flush_keeper();
|
|
}
|
|
|
|
void checkqueue() {
|
|
lnode_t *scannode;
|
|
scaninfo *scandata;
|
|
|
|
SET_SEGV_LOCATION();
|
|
|
|
/* exit, if the list is full */
|
|
if (list_isfull(opsbl) || list_isempty(opsbq))
|
|
return;
|
|
|
|
scannode = list_first(opsbq);
|
|
scandata = lnode_get(scannode);
|
|
list_delete(opsbq, scannode);
|
|
lnode_destroy(scannode);
|
|
startscan(scandata);
|
|
|
|
}
|
|
|
|
void addtocache(unsigned long ipaddr) {
|
|
lnode_t *cachenode;
|
|
C_entry *ce;
|
|
|
|
SET_SEGV_LOCATION();
|
|
|
|
/* pop off the oldest entry */
|
|
if (list_isfull(cache)) {
|
|
nlog(LOG_DEBUG2, LOG_MOD, "OPSB: Deleting Tail of Cache: %d", (int)list_count(cache));
|
|
cachenode = list_del_last(cache);
|
|
ce = lnode_get(cachenode);
|
|
lnode_destroy(cachenode);
|
|
free(ce);
|
|
}
|
|
cachenode = list_first(cache);
|
|
while (cachenode) {
|
|
ce = lnode_get(cachenode);
|
|
if (ce->ip == ipaddr) {
|
|
nlog(LOG_DEBUG2, LOG_MOD,"OPSB: Not adding %ld to cache as it already exists", ipaddr);
|
|
return;
|
|
}
|
|
cachenode = list_next(cache, cachenode);
|
|
}
|
|
|
|
ce = malloc(sizeof(C_entry));
|
|
ce->ip = ipaddr;
|
|
ce->when = time(NULL);
|
|
cachenode = lnode_create(ce);
|
|
list_prepend(cache, cachenode);
|
|
}
|
|
|
|
int checkcache(scaninfo *scandata) {
|
|
lnode_t *node, *node2;
|
|
C_entry *ce;
|
|
exemptinfo *exempts;
|
|
|
|
SET_SEGV_LOCATION();
|
|
|
|
node = list_first(exempt);
|
|
while (node) {
|
|
exempts = lnode_get(node);
|
|
if ((exempts->server == 1) && (scandata->server)) {
|
|
/* match a server */
|
|
if (fnmatch(exempts->host, scandata->server, 0) == 0) {
|
|
nlog(LOG_DEBUG1, LOG_MOD, "OPSB: User %s exempt. Matched server entry %s in Exemptions", scandata->who, exempts->host);
|
|
if (scandata->u) prefmsg(scandata->u->nick, s_opsb,"%s Matches a Server Exception %s", scandata->who, exempts->host);
|
|
return 1;
|
|
}
|
|
} else {
|
|
if (fnmatch(exempts->host, scandata->lookup, 0) == 0) {
|
|
nlog(LOG_DEBUG1, LOG_MOD, "OPSB: User %s exempt. Matched host entry %s in exemptions", scandata->who, exempts->host);
|
|
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "%s Matches a Host Exception %s", scandata->who, exempts->host);
|
|
return 2;
|
|
}
|
|
}
|
|
node = list_next(exempt, node);
|
|
}
|
|
node = list_first(cache);
|
|
while (node) {
|
|
ce = lnode_get(node);
|
|
|
|
/* delete any old cache entries */
|
|
|
|
if ((time(NULL) - ce->when) > opsb.cachetime) {
|
|
nlog(LOG_DEBUG1, LOG_MOD, "OPSB: Deleting old cache entry %ld", ce->ip);
|
|
node2 = list_next(cache, node);
|
|
list_delete(cache, node);
|
|
lnode_destroy(node);
|
|
free(ce);
|
|
node = node2;
|
|
break;
|
|
}
|
|
if (ce->ip == scandata->ipaddr.s_addr) {
|
|
nlog(LOG_DEBUG1, LOG_MOD, "OPSB: user %s is already in Cache", scandata->who);
|
|
opsb.cachehits++;
|
|
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "User %s is already in Cache", scandata->who);
|
|
return 3;
|
|
}
|
|
node = list_next(cache, node);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
EventFnList __module_events[] = {
|
|
{ EVENT_ONLINE, Online},
|
|
{ EVENT_SIGNON, ScanNick},
|
|
{ NULL, NULL}
|
|
};
|
|
|
|
/* this function kicks of a scan of a user that just signed on the network */
|
|
static int ScanNick(char **av, int ac) {
|
|
User *u;
|
|
scaninfo *scandata;
|
|
lnode_t *scannode;
|
|
lnode_t *node;
|
|
exemptinfo *exempts;
|
|
|
|
SET_SEGV_LOCATION();
|
|
|
|
/* don't do anything if NeoStats hasn't told us we are online yet */
|
|
if (!online)
|
|
return 0;
|
|
|
|
u = finduser(av[0]);
|
|
if (!u) {
|
|
nlog(LOG_WARNING, LOG_MOD, "OPSB: Ehhh, Can't find user %s", av[0]);
|
|
return -1;
|
|
}
|
|
|
|
/* don't scan users from my own server */
|
|
if (!strcasecmp(u->server->name, me.name)) {
|
|
return -1;
|
|
}
|
|
|
|
/* don't scan users from a server that is excluded */
|
|
node = list_first(exempt);
|
|
while (node) {
|
|
exempts = lnode_get(node);
|
|
if (exempts->server == 1) {
|
|
/* match a server */
|
|
if (fnmatch(exempts->host, u->server->name, 0) == 0) {
|
|
nlog(LOG_DEBUG1, LOG_MOD, "OPSB: User %s exempt. Matched server entry %s in Exemptions", u->nick, exempts->host);
|
|
return -1;
|
|
}
|
|
}
|
|
node = list_next(exempt, node);
|
|
}
|
|
|
|
if (time(NULL) - u->TS > opsb.timedif) {
|
|
nlog(LOG_DEBUG1, LOG_MOD, "Netsplit Nick %s, Not Scanning", av[0]);
|
|
return -1;
|
|
}
|
|
|
|
scannode = list_find(opsbl, av[0], findscan);
|
|
if (!scannode) scannode = list_find(opsbq, av[0], findscan);
|
|
if (scannode) {
|
|
nlog(LOG_DEBUG1, LOG_MOD, "ScanNick(): Not scanning %s as we are already scanning them", av[0]);
|
|
return -1;
|
|
}
|
|
prefmsg(u->nick, s_opsb, "%s", opsb.scanmsg);
|
|
scandata = malloc(sizeof(scaninfo));
|
|
scandata->u = NULL;
|
|
scandata->doneban = 0;
|
|
strlcpy(scandata->who, u->nick, MAXHOST);
|
|
strlcpy(scandata->lookup, u->hostname, MAXHOST);
|
|
strlcpy(scandata->server, u->server->name, MAXHOST);
|
|
strlcpy(scandata->connectstring, recbuf, BUFSIZE);
|
|
scandata->ipaddr.s_addr = u->ipaddr.s_addr;
|
|
if (scandata->ipaddr.s_addr > 0) {
|
|
scandata->dnsstate = DO_OPM_LOOKUP;
|
|
} else {
|
|
if (inet_aton(u->hostname, &scandata->ipaddr) > 0)
|
|
scandata->dnsstate = DO_OPM_LOOKUP;
|
|
else {
|
|
scandata->dnsstate = GET_NICK_IP;
|
|
scandata->ipaddr.s_addr = 0;
|
|
}
|
|
}
|
|
if (!startscan(scandata)) {
|
|
chanalert(s_opsb, "Warning Can't scan %s", u->nick);
|
|
nlog(LOG_WARNING, LOG_MOD, "OBSB ScanNick(): Can't scan %s. Check logs for possible errors", u->nick);
|
|
}
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
/* this function is the entry point for all scans. Any scan you want to kick off is started with this function. */
|
|
/* this includes moving scans from the queue to the active list */
|
|
|
|
int startscan(scaninfo *scandata) {
|
|
lnode_t *scannode;
|
|
unsigned char a, b, c, d;
|
|
char *buf;
|
|
int buflen;
|
|
int i;
|
|
|
|
SET_SEGV_LOCATION();
|
|
|
|
/* only check the cache when we have IP addy */
|
|
if (scandata->dnsstate == DO_OPM_LOOKUP) {
|
|
i = checkcache(scandata);
|
|
if ((i > 0) && (scandata->u == NULL)) {
|
|
free(scandata);
|
|
return 1;
|
|
}
|
|
}
|
|
switch(scandata->dnsstate) {
|
|
case GET_NICK_IP:
|
|
if (list_isfull(opsbl)) {
|
|
if (list_isfull(opsbq)) {
|
|
chanalert(s_opsb, "Warning, Both Current and queue lists are full. Not Adding additional scans");
|
|
nlog(LOG_DEBUG1, LOG_MOD, "OPSB: dropped scaning of %s, as queue is full", scandata->who);
|
|
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "To Busy. Try again later");
|
|
free(scandata);
|
|
return 0;
|
|
}
|
|
scannode = lnode_create(scandata);
|
|
list_append(opsbq, scannode);
|
|
nlog(LOG_DEBUG1, LOG_MOD, "DNS: Added %s to dns queue", scandata->who);
|
|
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "Your Request has been added to the Queue");
|
|
return 1;
|
|
}
|
|
if (dns_lookup(scandata->lookup, adns_r_a, dnsblscan, scandata->who) != 1) {
|
|
nlog(LOG_WARNING, LOG_MOD, "DNS: startscan() GET_NICK_IP dns_lookup() failed");
|
|
free(scandata);
|
|
checkqueue();
|
|
return 0;
|
|
}
|
|
|
|
scannode = lnode_create(scandata);
|
|
list_append(opsbl, scannode);
|
|
nlog(LOG_DEBUG1, LOG_MOD, "DNS: Added getnickip to DNS active list");
|
|
return 1;
|
|
break;
|
|
case DO_OPM_LOOKUP:
|
|
if (list_isfull(opsbl)) {
|
|
if(list_isfull(opsbq)) {
|
|
chanalert(s_opsb, "Warning, Both Current and Queue lists are full, Not adding Scan");
|
|
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "Too Busy. Try again Later");
|
|
free(scandata);
|
|
return 0;
|
|
}
|
|
scannode = lnode_create(scandata);
|
|
list_append(opsbq, scannode);
|
|
nlog(LOG_DEBUG1, LOG_MOD, "DNS: Added OPM lookup to queue: %s", scandata->who);
|
|
return 1;
|
|
}
|
|
d = (unsigned char) (scandata->ipaddr.s_addr >> 24) & 0xFF;
|
|
c = (unsigned char) (scandata->ipaddr.s_addr >> 16) & 0xFF;
|
|
b = (unsigned char) (scandata->ipaddr.s_addr >> 8) & 0xFF;
|
|
a = (unsigned char) scandata->ipaddr.s_addr & 0xFF;
|
|
|
|
/* Enough for a reversed IP and the zone. */
|
|
buflen = 18 + strlen(opsb.opmdomain);
|
|
buf = malloc(buflen * sizeof(*buf));
|
|
|
|
ircsnprintf(buf, buflen, "%d.%d.%d.%d.%s", d, c, b, a, opsb.opmdomain);
|
|
if (dns_lookup(buf, adns_r_a, dnsblscan, scandata->who) != 1) {
|
|
nlog(LOG_WARNING, LOG_MOD, "DNS: startscan() DO_OPM_LOOKUP dns_lookup() failed");
|
|
free(scandata);
|
|
free(buf);
|
|
checkqueue();
|
|
return 0;
|
|
}
|
|
scannode = lnode_create(scandata);
|
|
list_append(opsbl, scannode);
|
|
nlog(LOG_DEBUG1, LOG_MOD, "DNS: Added OPM %s lookup to DNS active list", buf);
|
|
free(buf);
|
|
start_proxy_scan(scannode);
|
|
++opsb.scanned;
|
|
return 1;
|
|
break;
|
|
default:
|
|
nlog(LOG_WARNING, LOG_MOD, "Warning, Unknown Status in startscan()");
|
|
free(scandata);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/* this function is called when either checking the opm list, or when we are trying to resolve the hostname */
|
|
|
|
void dnsblscan(char *data, adns_answer *a) {
|
|
lnode_t *scannode;
|
|
scaninfo *scandata;
|
|
char *show;
|
|
int len, ri;
|
|
|
|
SET_SEGV_LOCATION();
|
|
|
|
scannode = list_find(opsbl, data, findscan);
|
|
if (!scannode) {
|
|
nlog(LOG_CRITICAL, LOG_MOD, "dnsblscan(): Ehhh, Something is wrong here - Can't find %s", data);
|
|
return;
|
|
}
|
|
scandata = lnode_get(scannode);
|
|
if (a) {
|
|
switch(scandata->dnsstate) {
|
|
case GET_NICK_IP:
|
|
if (a->nrrs < 1) {
|
|
chanalert(s_opsb, "No Record for %s. Aborting Scan", scandata->lookup);
|
|
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "No A record for %s. Aborting Scan", scandata->lookup);
|
|
list_delete(opsbl, scannode);
|
|
lnode_destroy(scannode);
|
|
free(scandata);
|
|
checkqueue();
|
|
break;
|
|
}
|
|
adns_rr_info(a->type, 0, 0, &len, 0, 0);
|
|
ri = adns_rr_info(a->type, 0, 0, 0, a->rrs.bytes, &show);
|
|
if (!ri) {
|
|
nlog(LOG_DEBUG1, LOG_MOD, "DNS: Got IP for %s -> %s", scandata->who, show);
|
|
if (a->nrrs > 1) {
|
|
chanalert(s_opsb, "Warning, More than one IP address for %s. Using %s only", scandata->lookup, show);
|
|
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "Warning, More than one IP address for %s. Using %s only", scandata->lookup, show);
|
|
}
|
|
if (inet_aton(show, &scandata->ipaddr) > 0) {
|
|
scandata->dnsstate = DO_OPM_LOOKUP;
|
|
list_delete(opsbl, scannode);
|
|
lnode_destroy(scannode);
|
|
startscan(scandata);
|
|
} else {
|
|
nlog(LOG_CRITICAL, LOG_MOD, "DNS: dnsblscan() GETNICKIP failed-> %s", show);
|
|
chanalert(s_opsb, "Warning, Couldn't get the address for %s", scandata->who);
|
|
list_delete(opsbl, scannode);
|
|
lnode_destroy(scannode);
|
|
free(scandata);
|
|
checkqueue();
|
|
}
|
|
|
|
} else {
|
|
nlog(LOG_CRITICAL, LOG_MOD, "DNS: dnsblscan GETNICKIP rr_info failed");
|
|
chanalert(s_opsb, "Warning, Couldnt get the address for %s. rr_info failed", scandata->who);
|
|
list_delete(opsbl, scannode);
|
|
lnode_destroy(scannode);
|
|
free(scandata);
|
|
checkqueue();
|
|
}
|
|
free(show);
|
|
break;
|
|
case DO_OPM_LOOKUP:
|
|
if (a->nrrs > 0) {
|
|
/* TODO: print out what type of open proxy it is based on IP address returned */
|
|
nlog(LOG_NOTICE, LOG_MOD, "Got Positive OPM lookup for %s (%s)", scandata->who, scandata->lookup);
|
|
scandata->dnsstate = OPMLIST;
|
|
opsb.opmhits++;
|
|
chanalert(s_opsb, "Banning %s (%s) as its listed in %s", scandata->who, inet_ntoa(scandata->ipaddr), opsb.opmdomain);
|
|
globops(s_opsb, "Banning %s (%s) as its listed in %s", scandata->who, inet_ntoa(scandata->ipaddr), opsb.opmdomain);
|
|
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "Banning %s (%s) as its listed in %s", scandata->who, inet_ntoa(scandata->ipaddr), opsb.opmdomain);
|
|
sakill_cmd(inet_ntoa(scandata->ipaddr), "*", s_opsb, opsb.bantime, "Your host is listed as an Open Proxy. Please visit the following website for more info: www.blitzed.org/proxy?ip=%s", inet_ntoa(scandata->ipaddr));
|
|
checkqueue();
|
|
} else {
|
|
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "%s does not appear in DNS black list", scandata->lookup);
|
|
nlog(LOG_DEBUG1, LOG_MOD, "Got Negative OPM lookup for %s (%s)", scandata->who, scandata->lookup);
|
|
scandata->dnsstate = NOOPMLIST;
|
|
}
|
|
check_scan_free(scandata);
|
|
break;
|
|
default:
|
|
nlog(LOG_WARNING, LOG_MOD, "Warning, Unknown Status in dnsblscan()");
|
|
list_delete(opsbl, scannode);
|
|
lnode_destroy(scannode);
|
|
free(scandata);
|
|
return;
|
|
}
|
|
return;
|
|
} else {
|
|
nlog(LOG_CRITICAL, LOG_MOD, "OPSP() Answer is Empty!");
|
|
list_delete(opsbl, scannode);
|
|
lnode_destroy(scannode);
|
|
free(scandata);
|
|
}
|
|
}
|
|
|
|
/* this function is to send the results to the user after a lookup command */
|
|
|
|
void reportdns(char *data, adns_answer *a) {
|
|
lnode_t *dnslookup;
|
|
scaninfo *dnsinfo;
|
|
char *show;
|
|
int i, len, ri;
|
|
|
|
SET_SEGV_LOCATION();
|
|
|
|
dnslookup = list_find(opsbl, data, findscan);
|
|
if (!dnslookup) {
|
|
nlog(LOG_CRITICAL, LOG_MOD, "reportdns(): Ehhh, something wrong here %s", data);
|
|
return;
|
|
}
|
|
dnsinfo = lnode_get(dnslookup);
|
|
if (a) {
|
|
adns_rr_info(a->type, 0, 0, &len, 0, 0);
|
|
for(i = 0; i < a->nrrs; i++) {
|
|
ri = adns_rr_info(a->type, 0, 0, 0, a->rrs.bytes +i*len, &show);
|
|
if (!ri) {
|
|
prefmsg(data, s_opsb, "%s resolves to %s", dnsinfo->lookup, show);
|
|
} else {
|
|
prefmsg(data, s_opsb, "DNS error %s", adns_strerror(ri));
|
|
}
|
|
free(show);
|
|
}
|
|
if (a->nrrs < 1) {
|
|
prefmsg(data, s_opsb, "%s Does not resolve", dnsinfo->lookup);
|
|
}
|
|
} else {
|
|
prefmsg(data, s_opsb, "An unknown error occured");
|
|
}
|
|
|
|
list_delete(opsbl, dnslookup);
|
|
lnode_destroy(dnslookup);
|
|
free(dnsinfo);
|
|
checkqueue();
|
|
}
|
|
|
|
void LoadConfig(void)
|
|
{
|
|
int i;
|
|
lnode_t *node;
|
|
char **data;
|
|
char *tmp;
|
|
char datapath[BUFSIZE];
|
|
exemptinfo *exempts;
|
|
|
|
if (GetConf((void *) &tmp, CFGSTR, "Nick") < 0) {
|
|
strlcpy(s_opsb, "opsb", MAXNICK);
|
|
} else {
|
|
strlcpy(s_opsb, tmp, MAXNICK);
|
|
free(tmp);
|
|
}
|
|
if (GetConf((void *) &tmp, CFGSTR, "User") < 0) {
|
|
strlcpy(opsb.user, "opsb", MAXUSER);
|
|
} else {
|
|
strlcpy(opsb.user, tmp, MAXUSER);
|
|
free(tmp);
|
|
}
|
|
if (GetConf((void *) &tmp, CFGSTR, "Host") < 0) {
|
|
strlcpy(opsb.host, me.name, MAXHOST);
|
|
} else {
|
|
strlcpy(opsb.host, tmp, MAXHOST);
|
|
free(tmp);
|
|
}
|
|
if (GetConf((void *) &tmp, CFGSTR, "RealName") < 0) {
|
|
ircsnprintf(opsb.realname, MAXREALNAME, "Proxy Scanning Bot");
|
|
} else {
|
|
strlcpy(opsb.realname, tmp, MAXREALNAME);
|
|
free(tmp);
|
|
}
|
|
if (GetConf((void *)&tmp, CFGSTR, "OpmDomain") <= 0) {
|
|
strlcpy(opsb.opmdomain, "opm.blitzed.org", MAXHOST);
|
|
} else {
|
|
strlcpy(opsb.opmdomain, tmp, MAXHOST);
|
|
free(tmp);
|
|
}
|
|
if (GetConf((void *)&tmp, CFGSTR, "TargetHost") <= 0) {
|
|
strlcpy(opsb.targethost, me.uplink, MAXHOST);
|
|
} else {
|
|
strlcpy(opsb.targethost, tmp, MAXHOST);
|
|
free(tmp);
|
|
}
|
|
if (GetConf((void *)&opsb.targetport, CFGINT, "TargetPort") <= 0) {
|
|
opsb.targetport = me.port;
|
|
}
|
|
if (GetConf((void *)&opsb.maxbytes, CFGINT, "MaxBytes") <= 0) {
|
|
opsb.maxbytes = 500;
|
|
}
|
|
if (GetConf((void *)&opsb.timeout, CFGINT, "TimeOut") <= 0) {
|
|
opsb.timeout = 30;
|
|
}
|
|
if (GetConf((void *)&opsb.timedif, CFGINT, "SplitTime") <= 0) {
|
|
opsb.timedif = 600;
|
|
}
|
|
if (GetConf((void *)&opsb.cachetime, CFGINT, "CacheTime") <= 0) {
|
|
opsb.cachetime = 3600;
|
|
}
|
|
if (GetConf((void *)&opsb.verbose, CFGINT, "Verbose") <= 0) {
|
|
opsb.cachetime = 1;
|
|
}
|
|
if (GetConf((void *)&opsb.bantime, CFGINT, "BanTime") <= 0) {
|
|
opsb.bantime = 86400;
|
|
}
|
|
if (GetConf((void *)&opsb.doscan, CFGINT, "DoScan") <= 0) {
|
|
opsb.doscan = 1;
|
|
}
|
|
if (GetConf((void *)&opsb.doban, CFGINT, "DoBan") <= 0) {
|
|
opsb.doban = 1;
|
|
}
|
|
if (GetConf((void *)&opsb.confed, CFGINT, "Confed") <= 0) {
|
|
opsb.confed = 0;
|
|
}
|
|
|
|
if (GetConf((void *)&tmp, CFGSTR, "TriggerString") <= 0) {
|
|
strlcpy(opsb.lookforstring, "*** Looking up your hostname...", BUFSIZE);
|
|
} else {
|
|
strlcpy(opsb.lookforstring, tmp, BUFSIZE);
|
|
free(tmp);
|
|
}
|
|
if (GetConf((void *)&tmp, CFGSTR, "ScanMsg") <= 0) {
|
|
strlcpy(opsb.scanmsg, "Your Host is being Scanned for Open Proxies", BUFSIZE);
|
|
} else {
|
|
strlcpy(opsb.scanmsg, tmp, BUFSIZE);
|
|
free(tmp);
|
|
}
|
|
|
|
if (GetDir("Exempt", &data) > 0) {
|
|
/* try */
|
|
for (i = 0; data[i] != NULL; i++) {
|
|
exempts = malloc(sizeof(exemptinfo));
|
|
strlcpy(exempts->host, data[i], MAXHOST);
|
|
|
|
ircsnprintf(datapath, CONFBUFSIZE, "Exempt/%s/Who", data[i]);
|
|
if (GetConf((void *)&tmp, CFGSTR, datapath) <= 0) {
|
|
free(exempts);
|
|
continue;
|
|
} else {
|
|
strlcpy(exempts->who, tmp, MAXNICK);
|
|
free(tmp);
|
|
}
|
|
ircsnprintf(datapath, CONFBUFSIZE, "Exempt/%s/Reason", data[i]);
|
|
if (GetConf((void *)&tmp, CFGSTR, datapath) <= 0) {
|
|
free(exempts);
|
|
continue;
|
|
} else {
|
|
strlcpy(exempts->reason, tmp, MAXREASON);
|
|
free(tmp);
|
|
}
|
|
ircsnprintf(datapath, CONFBUFSIZE, "Exempt/%s/Server", data[i]);
|
|
if (GetConf((void *)&exempts->server, CFGINT, datapath) <= 0) {
|
|
free(exempts);
|
|
continue;
|
|
}
|
|
nlog(LOG_DEBUG2, LOG_MOD, "Adding %s (%d) Set by %s for %s to Exempt List", exempts->host, exempts->server, exempts->who, exempts->reason);
|
|
node = lnode_create(exempts);
|
|
list_prepend(exempt, node);
|
|
}
|
|
}
|
|
free(data);
|
|
}
|
|
|
|
int __ModInit(int modnum, int apiver)
|
|
{
|
|
#ifdef NS_ERR_VERSION /* Forward port version checks */
|
|
/* Check that our compiled version if compatible with the calling version of NeoStats */
|
|
if( ircstrncasecmp (me.version, NEOSTATS_VERSION, VERSIONSIZE) !=0) {
|
|
return NS_ERR_VERSION;
|
|
}
|
|
#endif
|
|
strlcpy(s_opsb, "opsb", MAXNICK);
|
|
/* we have to be careful here. Currently, we have 7 sockets that get opened per connection. Soooo.
|
|
* we check that MAX_SCANS is not greater than the maxsockets available / 7
|
|
* this way, we *shouldn't* get problems with running out of sockets
|
|
*/
|
|
if (MAX_SCANS > me.maxsocks / 7) {
|
|
opsbl = list_create(me.maxsocks /7);
|
|
opsb.socks = me.maxsocks /7;
|
|
} else {
|
|
opsbl = list_create(MAX_SCANS);
|
|
opsb.socks = MAX_SCANS;
|
|
}
|
|
/* queue can be anything we want */
|
|
opsbq = list_create(MAX_QUEUE);
|
|
/* scan cache is MAX_QUEUE size (why not?) */
|
|
cache = list_create(MAX_QUEUE);
|
|
exempt = list_create(MAX_EXEMPTS);
|
|
opsb.ports = list_create(MAX_PORTS);
|
|
LoadConfig();
|
|
online = 0;
|
|
opsb.open = 0;
|
|
opsb.scanned = 0;
|
|
opsb.cachehits = 1;
|
|
opsb.opmhits = 1;
|
|
if (load_ports() != 1) {
|
|
nlog(LOG_WARNING, LOG_MOD, "Can't Load opsb. No Ports Defined for Scanner. Did you install Correctly?");
|
|
return -1;
|
|
}
|
|
init_libopm();
|
|
return 1;
|
|
}
|
|
|
|
void __ModFini()
|
|
{
|
|
};
|
|
|
|
void save_exempts(exemptinfo *exempts)
|
|
{
|
|
char path[255];
|
|
|
|
nlog(LOG_DEBUG1, LOG_MOD, "Saving Exempt List %s", exempts->host);
|
|
ircsnprintf(path, 255, "Exempt/%s/Who", exempts->host);
|
|
SetConf((void *)exempts->who, CFGSTR, path);
|
|
ircsnprintf(path, 255, "Exempt/%s/Reason", exempts->host);
|
|
SetConf((void *)exempts->reason, CFGSTR, path);
|
|
ircsnprintf(path, 255, "Exempt/%s/Server", exempts->host);
|
|
SetConf((void *)exempts->server, CFGINT, path);
|
|
}
|