|
@@ -38,7 +38,7 @@ static time_t last_invtime = (time_t) 0L;
|
|
|
static char last_invchan[300] = "";
|
|
static char last_invchan[300] = "";
|
|
|
|
|
|
|
|
typedef struct resolvstruct {
|
|
typedef struct resolvstruct {
|
|
|
- struct chanset_t *chan;
|
|
|
|
|
|
|
+ char *chan;
|
|
|
char *host;
|
|
char *host;
|
|
|
bd::String* servers;
|
|
bd::String* servers;
|
|
|
bd::String* server;
|
|
bd::String* server;
|
|
@@ -47,9 +47,11 @@ typedef struct resolvstruct {
|
|
|
static void resolv_member_callback(int id, void *client_data, const char *host, bd::Array<bd::String> ips)
|
|
static void resolv_member_callback(int id, void *client_data, const char *host, bd::Array<bd::String> ips)
|
|
|
{
|
|
{
|
|
|
resolv_member *r = (resolv_member *) client_data;
|
|
resolv_member *r = (resolv_member *) client_data;
|
|
|
|
|
+ struct chanset_t* chan = NULL;
|
|
|
|
|
|
|
|
- if (!r || !r->chan || !r->host || !ips.size()) {
|
|
|
|
|
|
|
+ if (!r || !r->chan || !r->host || !ips.size() || !(chan = findchan_by_dname(r->chan))) {
|
|
|
if (r) {
|
|
if (r) {
|
|
|
|
|
+ if (r->chan) free(r->chan);
|
|
|
if (r->host) free(r->host);
|
|
if (r->host) free(r->host);
|
|
|
free(r);
|
|
free(r);
|
|
|
}
|
|
}
|
|
@@ -61,7 +63,7 @@ static void resolv_member_callback(int id, void *client_data, const char *host,
|
|
|
bool matched_user = 0;
|
|
bool matched_user = 0;
|
|
|
|
|
|
|
|
/* Apply lookup results to all matching members by host */
|
|
/* Apply lookup results to all matching members by host */
|
|
|
- for (m = r->chan->channel.member; m && m->nick[0]; m = m->next) {
|
|
|
|
|
|
|
+ for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
|
|
|
if (!m->userip[0] && m->userhost[0]) {
|
|
if (!m->userip[0] && m->userhost[0]) {
|
|
|
pe = strchr(m->userhost, '@');
|
|
pe = strchr(m->userhost, '@');
|
|
|
if (pe && !strcmp(pe + 1, r->host)) {
|
|
if (pe && !strcmp(pe + 1, r->host)) {
|
|
@@ -75,16 +77,17 @@ static void resolv_member_callback(int id, void *client_data, const char *host,
|
|
|
if (m->user)
|
|
if (m->user)
|
|
|
check_this_user(m->user->handle, 0, NULL);
|
|
check_this_user(m->user->handle, 0, NULL);
|
|
|
}
|
|
}
|
|
|
|
|
+ if (m->user)
|
|
|
|
|
+ matched_user = 1;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if (m->user)
|
|
|
|
|
- matched_user = 1;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!matched_user && channel_rbl(r->chan))
|
|
|
|
|
- resolve_to_rbl(r->chan, bd::String(ips[0]).c_str());
|
|
|
|
|
|
|
+ if (!matched_user && channel_rbl(chan))
|
|
|
|
|
+ resolve_to_rbl(chan, bd::String(ips[0]).c_str());
|
|
|
|
|
|
|
|
free(r->host);
|
|
free(r->host);
|
|
|
|
|
+ free(r->chan);
|
|
|
free(r);
|
|
free(r);
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
@@ -94,13 +97,14 @@ void resolve_to_member(struct chanset_t *chan, char *nick, char *host)
|
|
|
{
|
|
{
|
|
|
resolv_member *r = (resolv_member *) my_calloc(1, sizeof(resolv_member));
|
|
resolv_member *r = (resolv_member *) my_calloc(1, sizeof(resolv_member));
|
|
|
|
|
|
|
|
- r->chan = chan;
|
|
|
|
|
|
|
+ r->chan = strdup(chan->dname);
|
|
|
r->host = strdup(host);
|
|
r->host = strdup(host);
|
|
|
|
|
|
|
|
if (egg_dns_lookup(host, 20, resolv_member_callback, (void *) r) == -2) { //Already querying?
|
|
if (egg_dns_lookup(host, 20, resolv_member_callback, (void *) r) == -2) { //Already querying?
|
|
|
// Querying on clones will cause the callback to not be called and this nick will be ignored
|
|
// Querying on clones will cause the callback to not be called and this nick will be ignored
|
|
|
// cleanup memory as this chain is not even starting.
|
|
// cleanup memory as this chain is not even starting.
|
|
|
free(r->host);
|
|
free(r->host);
|
|
|
|
|
+ free(r->chan);
|
|
|
free(r);
|
|
free(r);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -109,46 +113,48 @@ void resolve_to_member(struct chanset_t *chan, char *nick, char *host)
|
|
|
static void resolve_rbl_callback(int id, void *client_data, const char *host, bd::Array<bd::String> ips)
|
|
static void resolve_rbl_callback(int id, void *client_data, const char *host, bd::Array<bd::String> ips)
|
|
|
{
|
|
{
|
|
|
resolv_member *r = (resolv_member *) client_data;
|
|
resolv_member *r = (resolv_member *) client_data;
|
|
|
|
|
+ struct chanset_t* chan = NULL;
|
|
|
|
|
|
|
|
- if (!r || !r->chan || !r->host || !ips.size()) {
|
|
|
|
|
- if (r && r->chan && r->host) {
|
|
|
|
|
|
|
+ if (!r || !r->chan || !r->host || !(chan = findchan_by_dname(r->chan)) || !ips.size()) {
|
|
|
|
|
+ if (r && chan && r->host) {
|
|
|
// Lookup from the next RBL
|
|
// Lookup from the next RBL
|
|
|
- resolve_to_rbl(r->chan, r->host, r);
|
|
|
|
|
|
|
+ resolve_to_rbl(chan, r->host, r);
|
|
|
}
|
|
}
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- sdprintf("RBL match for %s:%s: %s", r->chan->dname, r->host, bd::String(ips[0]).c_str());
|
|
|
|
|
|
|
+ sdprintf("RBL match for %s:%s: %s", chan->dname, r->host, bd::String(ips[0]).c_str());
|
|
|
|
|
|
|
|
char s1[UHOSTLEN] = "";
|
|
char s1[UHOSTLEN] = "";
|
|
|
simple_snprintf(s1, sizeof(s1), "*!*@%s", r->host);
|
|
simple_snprintf(s1, sizeof(s1), "*!*@%s", r->host);
|
|
|
|
|
|
|
|
bd::String reason = "Listed in RBL: " + *(r->server);
|
|
bd::String reason = "Listed in RBL: " + *(r->server);
|
|
|
|
|
|
|
|
- u_addmask('b', r->chan, s1, conf.bot->nick, reason.c_str(), now + (60 * (r->chan->ban_time ? r->chan->ban_time : 300)), 0);
|
|
|
|
|
|
|
+ u_addmask('b', chan, s1, conf.bot->nick, reason.c_str(), now + (60 * (chan->ban_time ? chan->ban_time : 300)), 0);
|
|
|
|
|
|
|
|
- if (me_op(r->chan)) {
|
|
|
|
|
- do_mask(r->chan, r->chan->channel.ban, s1, 'b');
|
|
|
|
|
|
|
+ if (me_op(chan)) {
|
|
|
|
|
+ do_mask(chan, chan->channel.ban, s1, 'b');
|
|
|
|
|
|
|
|
memberlist *m = NULL;
|
|
memberlist *m = NULL;
|
|
|
char *pe = NULL;
|
|
char *pe = NULL;
|
|
|
|
|
|
|
|
/* Apply lookup results to all matching members by host */
|
|
/* Apply lookup results to all matching members by host */
|
|
|
- for (m = r->chan->channel.member; m && m->nick[0]; m = m->next) {
|
|
|
|
|
|
|
+ for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
|
|
|
if (!m->user && !chan_sentkick(m) && m->userip[0]) {
|
|
if (!m->user && !chan_sentkick(m) && m->userip[0]) {
|
|
|
pe = strchr(m->userip, '@');
|
|
pe = strchr(m->userip, '@');
|
|
|
if (pe && !strcmp(pe + 1, r->host)) {
|
|
if (pe && !strcmp(pe + 1, r->host)) {
|
|
|
m->flags |= SENTKICK;
|
|
m->flags |= SENTKICK;
|
|
|
- dprintf(DP_MODE, "KICK %s %s :%s%s\n", r->chan->name, m->nick, bankickprefix, reason.c_str());
|
|
|
|
|
|
|
+ dprintf(DP_MODE, "KICK %s %s :%s%s\n", chan->name, m->nick, bankickprefix, reason.c_str());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- sdprintf("Done checking rbl (matched) for %s:%s", r->chan->dname, r->host);
|
|
|
|
|
|
|
+ sdprintf("Done checking rbl (matched) for %s:%s", chan->dname, r->host);
|
|
|
delete r->servers;
|
|
delete r->servers;
|
|
|
delete r->server;
|
|
delete r->server;
|
|
|
free(r->host);
|
|
free(r->host);
|
|
|
|
|
+ free(r->chan);
|
|
|
free(r);
|
|
free(r);
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
@@ -156,10 +162,14 @@ static void resolve_rbl_callback(int id, void *client_data, const char *host, bd
|
|
|
|
|
|
|
|
void resolve_to_rbl(struct chanset_t *chan, const char *host, resolv_member *r)
|
|
void resolve_to_rbl(struct chanset_t *chan, const char *host, resolv_member *r)
|
|
|
{
|
|
{
|
|
|
|
|
+ // Skip past user@ if present
|
|
|
|
|
+ char *p = strchr((char*)host, '@');
|
|
|
|
|
+ if (p)
|
|
|
|
|
+ host = p + 1;
|
|
|
if (!r) {
|
|
if (!r) {
|
|
|
r = (resolv_member *) my_calloc(1, sizeof(resolv_member));
|
|
r = (resolv_member *) my_calloc(1, sizeof(resolv_member));
|
|
|
|
|
|
|
|
- r->chan = chan;
|
|
|
|
|
|
|
+ r->chan = strdup(chan->dname);
|
|
|
r->host = strdup(host);
|
|
r->host = strdup(host);
|
|
|
r->servers = new bd::String(rbl_servers);
|
|
r->servers = new bd::String(rbl_servers);
|
|
|
r->server = new bd::String;
|
|
r->server = new bd::String;
|
|
@@ -172,16 +182,28 @@ void resolve_to_rbl(struct chanset_t *chan, const char *host, resolv_member *r)
|
|
|
delete r->servers;
|
|
delete r->servers;
|
|
|
delete r->server;
|
|
delete r->server;
|
|
|
free(r->host);
|
|
free(r->host);
|
|
|
|
|
+ free(r->chan);
|
|
|
free(r);
|
|
free(r);
|
|
|
return; //No more servers
|
|
return; //No more servers
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
*(r->server) = rbl_server;
|
|
*(r->server) = rbl_server;
|
|
|
|
|
|
|
|
- size_t iplen = strlen(host) + 1 + rbl_server.length() + 1;
|
|
|
|
|
|
|
+ size_t iplen = rbl_server.length() + 1;
|
|
|
|
|
+ bool v6 = 0;
|
|
|
|
|
+ if (strchr(host, ':')) {
|
|
|
|
|
+ v6 = 1;
|
|
|
|
|
+ iplen += 128 + 1;
|
|
|
|
|
+ } else
|
|
|
|
|
+ iplen += strlen(host) + 1;
|
|
|
|
|
+
|
|
|
char *ip = (char *) my_calloc(1, iplen);
|
|
char *ip = (char *) my_calloc(1, iplen);
|
|
|
- reverse_ip(host, ip);
|
|
|
|
|
- strlcat(ip, ".", iplen);
|
|
|
|
|
|
|
+ if (v6)
|
|
|
|
|
+ socket_ipv6_to_dots(host, ip);
|
|
|
|
|
+ else {
|
|
|
|
|
+ reverse_ip(host, ip);
|
|
|
|
|
+ strlcat(ip, ".", iplen);
|
|
|
|
|
+ }
|
|
|
strlcat(ip, rbl_server.c_str(), iplen);
|
|
strlcat(ip, rbl_server.c_str(), iplen);
|
|
|
|
|
|
|
|
if (egg_dns_lookup(ip, 20, resolve_rbl_callback, (void *) r, DNS_A) == -2) { //Already querying?
|
|
if (egg_dns_lookup(ip, 20, resolve_rbl_callback, (void *) r, DNS_A) == -2) { //Already querying?
|
|
@@ -190,6 +212,7 @@ void resolve_to_rbl(struct chanset_t *chan, const char *host, resolv_member *r)
|
|
|
delete r->servers;
|
|
delete r->servers;
|
|
|
delete r->server;
|
|
delete r->server;
|
|
|
free(r->host);
|
|
free(r->host);
|
|
|
|
|
+ free(r->chan);
|
|
|
free(r);
|
|
free(r);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1899,7 +1922,7 @@ static int got352or4(struct chanset_t *chan, char *user, char *host, char *nick,
|
|
|
if (!m->userip[0] && doresolv(chan))
|
|
if (!m->userip[0] && doresolv(chan))
|
|
|
resolve_to_member(chan, nick, host);
|
|
resolve_to_member(chan, nick, host);
|
|
|
else if (!me && !m->user && m->userip[0] && doresolv(chan) && channel_rbl(chan))
|
|
else if (!me && !m->user && m->userip[0] && doresolv(chan) && channel_rbl(chan))
|
|
|
- resolve_to_rbl(chan, host);
|
|
|
|
|
|
|
+ resolve_to_rbl(chan, m->userip);
|
|
|
|
|
|
|
|
|
|
|
|
|
get_user_flagrec(m->user, &fr, chan->dname, chan);
|
|
get_user_flagrec(m->user, &fr, chan->dname, chan);
|
|
@@ -2604,7 +2627,7 @@ static int gotjoin(char *from, char *chname)
|
|
|
if (is_dotted_ip(host)) {
|
|
if (is_dotted_ip(host)) {
|
|
|
strlcpy(m->userip, uhost, sizeof(m->userip));
|
|
strlcpy(m->userip, uhost, sizeof(m->userip));
|
|
|
if (channel_rbl(chan))
|
|
if (channel_rbl(chan))
|
|
|
- resolve_to_rbl(chan, host);
|
|
|
|
|
|
|
+ resolve_to_rbl(chan, m->userip);
|
|
|
} else
|
|
} else
|
|
|
resolve_to_member(chan, nick, host);
|
|
resolve_to_member(chan, nick, host);
|
|
|
}
|
|
}
|
|
@@ -2627,7 +2650,7 @@ static int gotjoin(char *from, char *chname)
|
|
|
if (!m->userip[0] && doresolv(chan))
|
|
if (!m->userip[0] && doresolv(chan))
|
|
|
resolve_to_member(chan, nick, host);
|
|
resolve_to_member(chan, nick, host);
|
|
|
else if (!m->user && m->userip[0] && doresolv(chan) && channel_rbl(chan))
|
|
else if (!m->user && m->userip[0] && doresolv(chan) && channel_rbl(chan))
|
|
|
- resolve_to_rbl(chan, host);
|
|
|
|
|
|
|
+ resolve_to_rbl(chan, m->userip);
|
|
|
|
|
|
|
|
// m->flags |= STOPWHO;
|
|
// m->flags |= STOPWHO;
|
|
|
|
|
|