]> jfr.im git - irc/quakenet/newserv.git/commitdiff
Added nickbanned_visible() and nickmatchban_visible().
authorsplidge <redacted>
Wed, 19 Mar 2008 11:39:48 +0000 (11:39 +0000)
committersplidge <redacted>
Wed, 19 Mar 2008 11:39:48 +0000 (11:39 +0000)
These functions act like their normal counterparts but don't check non-visible things.  This basically means the real ident isn't checked for +h users with a fake ident, and the real host and IP isn't checked for +h/+rx users.

channel/channel.h
channel/channelbans.c

index 846cc2729e128e3c6803923860abab34a7461994..cc4d1656565e6295e29790c196bcb3b535d62a86 100644 (file)
@@ -169,6 +169,8 @@ int clearban(channel *cp, const char *ban, int optional);
 void clearallbans(channel *cp);
 int nickmatchban(nick *np, chanban *bp);
 int nickbanned(nick *np, channel *cp);
+int nickmatchban_visible(nick *np, chanban *bp);
+int nickbanned_visible(nick *np, channel *cp);
 
 /* functions from channelindex.c */
 void initchannelindex();
index 8c3255c794c8c1a650efe465f8d5060ef817b7af..8d1fed02eb0ac9f750f8eb59bdd33204c355e4c6 100644 (file)
 #include "../irc/irc_config.h"
 #include "../irc/irc.h"
 
+/*
+ * nickmatchban_visible:
+ *  Returns true iff the supplied nick* matches the supplied ban* 
+ *  Doesn't check "invisible" things like true hosts and IPs for 
+ *  +x/+h users.
+ *
+ * copy & pasted this, touch and go whether this was a good idea.
+ */
+
+int nickmatchban_visible(nick *np, chanban *bp) {
+  const char *ipstring;
+  char fakehost[HOSTLEN+1];
+  char *visibleident;
+
+  /* Don't waste time on invalid bans */
+  if (bp->flags & CHANBAN_INVALID)
+    return 0;
+
+  /* nick/ident section: return 0 (no match) if they don't match */
+
+  /* Determine the visible ident for sethost users.  Don't test the real one. */  
+  if (IsSetHost(np) && np->shident && *np->shident)
+    visibleident=np->shident->content;
+  else
+    visibleident=np->ident;
+  
+  if (bp->flags & CHANBAN_USEREXACT && ircd_strcmp(visibleident,bp->user->content))
+    return 0;
+  
+  if (bp->flags & CHANBAN_NICKEXACT && ircd_strcmp(np->nick,bp->nick->content))
+    return 0;
+  
+  if (bp->flags & CHANBAN_USERMASK && !match2strings(bp->user->content,visibleident))
+    return 0;
+  
+  if (bp->flags & CHANBAN_NICKMASK && !match2strings(bp->nick->content,np->nick))
+    return 0;
+  
+  /* host section.  Return 1 (match) if they do match
+   * Note that if user or ident was specified, they've already been checked
+   */
+
+  if (bp->flags & CHANBAN_HOSTANY)
+    return 1;
+
+  if ((bp->flags & CHANBAN_CIDR) && (bp->flags & CHANBAN_HOSTEXACT)) {
+    unsigned int cip;
+    unsigned char *ch;
+
+    /* CIDR bans don't visibly match sethosted users */
+    if (IsSetHost(np) || (IsAccount(np) && IsHideHost(np)))
+      return 0;
+
+    /* CIDR bans don't match IPv6 hosts */
+    if (!irc_in_addr_is_ipv4(&(np->p_ipaddr)))
+      return 0;
+
+    /* Extract the client's IP address into a usable format */
+    ch=(unsigned char *)&(np->p_ipaddr.in6_16[6]);
+    cip=(ch[0]<<24) | (ch[1]<<16) | (ch[2]<<8) | (ch[3]);
+    
+    if ((cip & bp->mask) == bp->ipaddr)
+      return 1;
+    
+    return 0; /* A CIDR ban won't match any other way */
+  }
+  
+  if (bp->flags & CHANBAN_IP) {
+    /* IP bans don't match sethosted users */
+    if (IsSetHost(np) || (IsAccount(np) && IsHideHost(np)))
+      return 0;
+      
+    if (bp->flags & CHANBAN_HOSTEXACT) {
+      /* If it's an exact IP ban we can compare it numerically */
+      unsigned int cip;
+      unsigned char *ch;
+
+      /* Well, it won't match if it's not an IPv4 host */
+      if (!irc_in_addr_is_ipv4(&(np->p_ipaddr)))
+        return 0;
+
+      /* Extract the client's IP address into a usable format */
+      ch=(unsigned char *)&(np->p_ipaddr.in6_16[6]);
+      cip=(ch[0]<<24) | (ch[1]<<16) | (ch[2]<<8) | (ch[3]);
+
+      if (cip==bp->ipaddr) 
+        return 1;
+    } else {
+      /* It's not an exact IP ban so let's generate the string */
+      ipstring=IPtostr(np->p_ipaddr);
+      if (bp->flags & CHANBAN_HOSTMASK && match2strings(bp->host->content,ipstring))
+        return 1;
+    }
+  } else {
+    /* Hostname bans need to be checked against +x host, +h host (if set) 
+     * and actual host.  Note that the +x host is only generated (and checked) if it's
+     * possible for the ban to match a hidden host.. */
+
+    if ((bp->flags & CHANBAN_HIDDENHOST) && IsAccount(np)) {
+      sprintf(fakehost,"%s.%s",np->authname, HIS_HIDDENHOST);
+      
+      if ((bp->flags & CHANBAN_HOSTEXACT) && 
+         !ircd_strcmp(fakehost, bp->host->content))
+       return 1;
+      
+      if ((bp->flags & CHANBAN_HOSTMASK) &&
+         match2strings(bp->host->content, fakehost))
+       return 1;
+    }
+    
+    if (IsSetHost(np)) {
+      if ((bp->flags & CHANBAN_HOSTEXACT) &&
+         !ircd_strcmp(np->sethost->content, bp->host->content))
+       return 1;
+      
+      if ((bp->flags & CHANBAN_HOSTMASK) &&
+         match2strings(bp->host->content, np->sethost->content))
+       return 1;
+    }
+
+    /* If the user is +h or +rx don't check their real host */
+    if (IsSetHost(np) || (IsHideHost(np) && IsAccount(np)))
+      return 0;
+      
+    if (bp->flags & CHANBAN_HOSTEXACT && !ircd_strcmp(np->host->name->content,bp->host->content))
+      return 1;
+    
+    if (bp->flags & CHANBAN_HOSTMASK && match2strings(bp->host->content,np->host->name->content))
+      return 1;
+  }
+  
+  return 0;
+}
+
 /*
  * nickmatchban:
  *  Returns true iff the supplied nick* matches the supplied ban* 
@@ -130,18 +265,28 @@ int nickmatchban(nick *np, chanban *bp) {
 /*
  * nickbanned:
  *  Returns true iff the supplied nick* is banned on the supplied chan*
+ * 
+ * Also nickbanned_visible - doesn't violate privacy by checking hidden
+ * hosts and idents.  Factored into one function to reduce copy&paste.
  */
-
-int nickbanned(nick *np, channel *cp) {
+static int nickbanned_real(nick *np, channel *cp, int (*cmpfunc)(nick *, chanban *)) {
   chanban *cbp;
 
   for (cbp=cp->bans;cbp;cbp=cbp->next) {
-    if (nickmatchban(np,cbp))
+    if (cmpfunc(np,cbp))
       return 1; 
   }
 
   return 0;
 }
+
+int nickbanned(nick *np, channel *cp) {
+  return nickbanned_real(np,cp,nickmatchban);
+}
+
+int nickbanned_visible(nick *np, channel *cp) {
+  return nickbanned_real(np,cp,nickmatchban_visible);
+}
               
 /*
  * setban: