if(messagelen>0)
message[0] = '\0';
- if(!th || !trustsdbloaded)
+ if(!th || !trustsdbloaded || irc_in_addr_is_loopback(ip))
return POLICY_SUCCESS;
tg = th->group;
*/
if(hooknum == HOOK_TRUSTS_NEWNICK) {
- patricia_node_t *head, *node;
+ patricia_node_t *node;
int nodecount = 0;
- head = refnode(iptree, ip, th->nodebits);
- PATRICIA_WALK(head, node)
- {
- nodecount += node->usercount;
- }
- PATRICIA_WALK_END;
- derefnode(iptree, head);
+ node = refnode(iptree, ip, th->nodebits);
+ nodecount = node->usercount;
+ derefnode(iptree, node);
if(th->maxpernode && nodecount + usercountadjustment > th->maxpernode) {
- controlwall(NO_OPER, NL_TRUSTS, "Hard connection limit exceeded on subnet: %s (group: %s): %d connected, %d max.", trusts_cidr2str(ip, th->nodebits), tg->name->content, nodecount + usercountadjustment, th->maxpernode);
- snprintf(message, messagelen, "Too many connections from your host (%s) - see http://www.quakenet.org/help/trusts/connection-limit for details.", IPtostr(*ip));
+ controlwall(NO_OPER, NL_CLONING, "Hard connection limit exceeded on subnet: %s (group: %s): %d connected, %d max.", CIDRtostr(*ip, th->nodebits), tg->name->content, nodecount + usercountadjustment, th->maxpernode);
+ snprintf(message, messagelen, "Too many connections from your host (%s) - see https://www.quakenet.org/help/trusts/connection-limit for details.", IPtostr(*ip));
return POLICY_FAILURE_NODECOUNT;
}
if(tg->count > (long)tg->exts[countext]) {
tg->exts[countext] = (void *)(long)tg->count;
- controlwall(NO_OPER, NL_TRUSTS, "Hard connection limit exceeded (group %s): %d connected, %d max.", tg->name->content, tg->count + usercountadjustment, tg->trustedfor);
- snprintf(message, messagelen, "Too many connections from your trust (%s) - see http://www.quakenet.org/help/trusts/connection-limit for details.", IPtostr(*ip));
+ controlwall(NO_OPER, NL_CLONING, "Hard connection limit exceeded (group %s): %d connected, %d max.", tg->name->content, tg->count + usercountadjustment, tg->trustedfor);
+ snprintf(message, messagelen, "Too many connections from your trust (%s) - see https://www.quakenet.org/help/trusts/connection-limit for details.", IPtostr(*ip));
}
- snprintf(message, messagelen, "Too many connections from your trust (%s) - see http://www.quakenet.org/help/trusts/connection-limit for details.", IPtostr(*ip));
+ snprintf(message, messagelen, "Too many connections from your trust (%s) - see https://www.quakenet.org/help/trusts/connection-limit for details.", IPtostr(*ip));
return POLICY_FAILURE_GROUPCOUNT;
}
if((tg->flags & TRUST_ENFORCE_IDENT) && (username[0] == '~')) {
- controlwall(NO_OPER, NL_TRUSTS, "Ident required: %s@%s (group: %s).", username, IPtostr(*ip), tg->name->content);
- snprintf(message, messagelen, "IDENTD required from your host (%s) - see http://www.quakenet.org/help/trusts/connection-limit for details.", IPtostr(*ip));
+ controlwall(NO_OPER, NL_CLONING, "Ident required: %s@%s (group: %s).", username, IPtostr(*ip), tg->name->content);
+ snprintf(message, messagelen, "IDENTD required from your host (%s) - see https://www.quakenet.org/help/trusts/connection-limit for details.", IPtostr(*ip));
return POLICY_FAILURE_IDENTD;
}
}
if(identcount + usercountadjustment > tg->maxperident) {
- controlwall(NO_OPER, NL_TRUSTS, "Hard ident limit exceeded: %s@%s (group: %s): %d connected, %d max.", username, IPtostr(*ip), tg->name->content, identcount + usercountadjustment, tg->maxperident);
- snprintf(message, messagelen, "Too many connections from your username (%s@%s) - see http://www.quakenet.org/help/trusts/connection-limit for details.", username, IPtostr(*ip));
+ controlwall(NO_OPER, NL_CLONING, "Hard ident limit exceeded: %s@%s (group: %s): %d connected, %d max.", username, IPtostr(*ip), tg->name->content, identcount + usercountadjustment, tg->maxperident);
+ snprintf(message, messagelen, "Too many connections from your username (%s@%s) - see https://www.quakenet.org/help/trusts/connection-limit for details.", username, IPtostr(*ip));
return POLICY_FAILURE_IDENTCOUNT;
}
}
} else {
sock->rejected++;
- controlwall(NO_OPER, NL_TRUSTS, "Rejected connection from %s@%s using IAuth: %s", username, host, message);
+ controlwall(NO_OPER, NL_CLONING, "Rejected connection from %s@%s using IAuth: %s", username, host, message);
return trustdowrite(sock, "KILL %s %s", sequence_id, message);
}
}
return 0;
}
-static void trustfreeconnection(trustsocket *sock) {
- trustsocket **pnext = &tslist;
-
- for(trustsocket *ts=tslist;ts;ts=ts->next) {
+static void trustfreeconnection(trustsocket *sock, int unlink) {
+ trustsocket **pnext, *ts;
+
+ if(!unlink) {
+ controlwall(NO_OPER, NL_TRUSTS, "Lost connection on policy socket for '%s'.", sock->authed?sock->authuser:"<unauthenticated connection>");
+
+ deregisterhandler(sock->fd, 1);
+ nsfree(POOL_TRUSTS, sock);
+ return;
+ }
+
+ pnext = &tslist;
+
+ for(ts=*pnext;*pnext;pnext=&((*pnext)->next)) {
if(ts == sock) {
- deregisterhandler(sock->fd, 1);
*pnext = sock->next;
- nsfree(POOL_TRUSTS, sock);
+ trustfreeconnection(sock, 0);
break;
}
-
- pnext = &(sock->next);
}
}
policycheck_auth(sock, tokens[0], tokens[1], tokens[2]);
return 1;
+ } else if(!strcmp("VERSION", command)) {
+ /* Ignore this command for now. */
+ return 1;
} else {
Error("trusts_policy", ERR_WARNING, "Bad command: %s", command);
return 0;
if(!sock)
return;
-
+
+ if (events & (POLLPRI | POLLERR | POLLHUP | POLLNVAL)) {
+ trustfreeconnection(sock, 1);
+ return;
+ }
+
if(events & POLLIN)
if(!handletrustclient(sock))
- trustfreeconnection(sock);
+ trustfreeconnection(sock, 1);
}
static void trustdotimeout(void *arg) {
time_t t = time(NULL);
- trustsocket **pnext, *next, *sock;
+ trustsocket **pnext, *sock;
pnext = &tslist;
- for(sock=tslist;sock;) {
- next = sock->next;
-
+ for(sock=*pnext;*pnext;pnext=&((*pnext)->next)) {
if(!sock->authed && t >= sock->timeout) {
trustkillconnection(sock, "Auth timeout.");
- deregisterhandler(sock->fd, 1);
*pnext = sock->next;
- nsfree(POOL_TRUSTS, sock);
- } else {
- pnext = &(sock->next);
+ trustfreeconnection(sock, 0);
}
-
- sock=next;
}
}
long moving = (long)args[1];
char message[512];
int verdict;
+ struct irc_in_addr ipaddress_canonical;
if(moving)
return;
- verdict = checkconnectionth(np->ident, &np->p_nodeaddr, gettrusthost(np), hooknum, 0, message, sizeof(message));
+ ip_canonicalize_tunnel(&ipaddress_canonical, &np->ipaddress);
+
+ verdict = checkconnectionth(np->ident, &ipaddress_canonical, gettrusthost(np), hooknum, 0, message, sizeof(message));
if(!enforcepolicy_irc)
verdict = POLICY_SUCCESS;
glinebynick(np, POLICY_GLINE_DURATION, message, GLINE_IGNORE_TRUST, "trusts_policy");
break;
case POLICY_FAILURE_IDENTD:
- glinebyip("~*", &np->p_ipaddr, 128, POLICY_GLINE_DURATION, message, GLINE_ALWAYS_USER|GLINE_IGNORE_TRUST, "trusts_policy");
+ glinebyip("~*", &np->ipaddress, 128, POLICY_GLINE_DURATION, message, GLINE_ALWAYS_USER|GLINE_IGNORE_TRUST, "trusts_policy");
break;
case POLICY_FAILURE_IDENTCOUNT:
glinebynick(np, POLICY_GLINE_DURATION, message, GLINE_ALWAYS_USER|GLINE_IGNORE_TRUST, "trusts_policy");
time(&now);
- controlreply(sender, "Server Connected for Accepted Rejected");
+ controlreply(sender, "Server Connected for Accepted Rejected");
for(sock=tslist;sock;sock=sock->next)
- controlreply(sender, "%-20s %20s %10d %15d", sock->authed?sock->authuser:"<not authenticated>", longtoduration(now - sock->connected, 0), sock->accepted, sock->rejected);
+ controlreply(sender, "%-35s %-20s %-15d %-15d", sock->authed?sock->authuser:"<unauthenticated connection>", longtoduration(now - sock->connected, 0), sock->accepted, sock->rejected);
controlreply(sender, "-- End of list.");
return CMD_OK;
next = sock->next;
trustkillconnection(sock, "Unloading module.");
- trustfreeconnection(sock);
+ trustfreeconnection(sock, 0);
sock = next;
}