]> jfr.im git - irc/quakenet/newserv.git/blobdiff - trusts/trusts_policy.c
Merge default.
[irc/quakenet/newserv.git] / trusts / trusts_policy.c
index e394f91f7141aebad091eeef0185ff12a649dc24..a14af1ad27ec035d82f3d3dffc8796277a2a09be 100644 (file)
@@ -70,7 +70,7 @@ static int checkconnectionth(const char *username, struct irc_in_addr *ip, trust
   if(messagelen>0)
     message[0] = '\0';
   
-  if(!th || !trustsdbloaded)
+  if(!th || !trustsdbloaded || irc_in_addr_is_loopback(ip))
     return POLICY_SUCCESS;
 
   tg = th->group;
@@ -83,20 +83,16 @@ static int checkconnectionth(const char *username, struct irc_in_addr *ip, trust
    */
 
   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;
     }
 
@@ -104,17 +100,17 @@ static int checkconnectionth(const char *username, struct irc_in_addr *ip, trust
       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;
     }
 
@@ -131,8 +127,8 @@ static int checkconnectionth(const char *username, struct irc_in_addr *ip, trust
       }
 
       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;
       }
     }
@@ -199,7 +195,7 @@ static int policycheck_auth(trustsocket *sock, const char *sequence_id, const ch
   } 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);
   }
 }
@@ -209,18 +205,25 @@ static int trustkillconnection(trustsocket *sock, char *reason) {
   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);
   }
 }
 
@@ -296,6 +299,9 @@ static int handletrustline(trustsocket *sock, char *line) {
 
     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;
@@ -349,28 +355,21 @@ static void processtrustclient(int fd, short events) {
   
   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;
   }
 }
 
@@ -533,10 +532,10 @@ static int trusts_cmdtrustsockets(void *source, int cargc, char **cargv) {
 
   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, "%-30s %-20s %-10d %-15d", sock->authed?sock->authuser:"<unauthenticated connection>", longtoduration(now - sock->connected, 0), sock->accepted, sock->rejected);
 
   controlreply(sender, "-- End of list.");
   return CMD_OK;
@@ -654,7 +653,7 @@ void _fini(void) {
     next = sock->next;
 
     trustkillconnection(sock, "Unloading module.");
-    trustfreeconnection(sock);
+    trustfreeconnection(sock, 0);
 
     sock = next;
   }