]> jfr.im git - solanum.git/blobdiff - ircd/hostmask.c
Implement hook priorities
[solanum.git] / ircd / hostmask.c
index 059c07c774f2fc963d9b3d13a8cf31493e564850..942140411614b4f93e55ddc6736dcaa239ab217e 100644 (file)
@@ -31,9 +31,7 @@
 #include "send.h"
 #include "match.h"
 
-#ifdef RB_IPV6
 static unsigned long hash_ipv6(struct sockaddr *, int);
-#endif
 static unsigned long hash_ipv4(struct sockaddr *, int);
 
 
@@ -65,7 +63,6 @@ parse_netmask(const char *text, struct rb_sockaddr_storage *naddr, int *nb)
        {
                return HM_HOST;
        }
-#ifdef RB_IPV6
        if(strchr(ip, ':'))
        {
                if((ptr = strchr(ip, '/')))
@@ -79,12 +76,11 @@ parse_netmask(const char *text, struct rb_sockaddr_storage *naddr, int *nb)
                                return HM_HOST;
                } else
                        *b = 128;
-               if(rb_inet_pton_sock(ip, (struct sockaddr *)addr) > 0)
+               if(rb_inet_pton_sock(ip, addr) > 0)
                        return HM_IPV6;
                else
                        return HM_HOST;
        } else
-#endif
        if(strchr(text, '.'))
        {
                if((ptr = strchr(ip, '/')))
@@ -98,7 +94,7 @@ parse_netmask(const char *text, struct rb_sockaddr_storage *naddr, int *nb)
                                return HM_HOST;
                } else
                        *b = 32;
-               if(rb_inet_pton_sock(ip, (struct sockaddr *)addr) > 0)
+               if(rb_inet_pton_sock(ip, addr) > 0)
                        return HM_IPV4;
                else
                        return HM_HOST;
@@ -139,7 +135,6 @@ hash_ipv4(struct sockaddr *saddr, int bits)
  * Output: A hash value of the IP address.
  * Side effects: None
  */
-#ifdef RB_IPV6
 static unsigned long
 hash_ipv6(struct sockaddr *saddr, int bits)
 {
@@ -162,7 +157,6 @@ hash_ipv6(struct sockaddr *saddr, int bits)
        }
        return v & (ATABLE_SIZE - 1);
 }
-#endif
 
 /* int hash_text(const char *start)
  * Input: The start of the text to hash.
@@ -204,6 +198,9 @@ get_mask_hash(const char *text)
 
 /* struct ConfItem* find_conf_by_address(const char*, struct rb_sockaddr_storage*,
  *         int type, int fam, const char *username)
+ *
+ * This process needs to be kept in sync with check_one_kline().
+ *
  * Input: The hostname, the address, the type of mask to find, the address
  *        family, the username.
  * Output: The matching value with the highest precedence.
@@ -219,6 +216,8 @@ find_conf_by_address(const char *name, const char *sockhost,
        unsigned long hprecv = 0;
        struct ConfItem *hprec = NULL;
        struct AddressRec *arec;
+       struct sockaddr_in ip4;
+       struct sockaddr *pip4 = NULL;
        int b;
 
        if(username == NULL)
@@ -226,10 +225,13 @@ find_conf_by_address(const char *name, const char *sockhost,
 
        if(addr)
        {
-               /* Check for IPV6 matches... */
-#ifdef RB_IPV6
-               if(fam == AF_INET6)
+               if (fam == AF_INET)
+                       pip4 = addr;
+
+               if (fam == AF_INET6)
                {
+                       if (type == CONF_KILL && rb_ipv4_from_ipv6((struct sockaddr_in6 *)addr, &ip4))
+                               pip4 = (struct sockaddr *)&ip4;
 
                        for (b = 128; b >= 0; b -= 16)
                        {
@@ -248,16 +250,15 @@ find_conf_by_address(const char *name, const char *sockhost,
                                        }
                        }
                }
-               else
-#endif
-               if(fam == AF_INET)
+
+               if (pip4 != NULL)
                {
                        for (b = 32; b >= 0; b -= 8)
                        {
-                               for (arec = atable[hash_ipv4(addr, b)]; arec; arec = arec->next)
+                               for (arec = atable[hash_ipv4(pip4, b)]; arec; arec = arec->next)
                                        if(arec->type == (type & ~0x1) &&
                                           arec->masktype == HM_IPV4 &&
-                                          comp_with_mask_sock(addr, (struct sockaddr *)&arec->Mask.ipa.addr,
+                                          comp_with_mask_sock(pip4, (struct sockaddr *)&arec->Mask.ipa.addr,
                                                               arec->Mask.ipa.bits) &&
                                                (type & 0x1 || match(arec->username, username)) &&
                                                (type != CONF_CLIENT || !arec->auth_user ||
@@ -369,9 +370,6 @@ find_address_conf(const char *host, const char *sockhost, const char *user,
 {
        struct ConfItem *iconf, *kconf;
        const char *vuser;
-#ifdef RB_IPV6
-       struct sockaddr_in ip4;
-#endif
 
        /* Find the best I-line... If none, return NULL -A1kmm */
        if(!(iconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_CLIENT, aftype, user, auth_user)))
@@ -385,34 +383,38 @@ find_address_conf(const char *host, const char *sockhost, const char *user,
        if(IsConfExemptKline(iconf))
                return iconf;
 
-       /* Find the best K-line... -A1kmm */
-       kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, user, NULL);
-
-       /* If they are K-lined, return the K-line */
-       if(kconf)
-               return kconf;
-
        /* if theres a spoof, check it against klines.. */
        if(IsConfDoSpoofIp(iconf))
        {
                char *p = strchr(iconf->info.name, '@');
 
                /* note, we dont need to pass sockhost here, as its
-                * guaranteed to not match by whats above.. --anfl
+                * guaranteed to not match by whats below.. --anfl
                 */
                if(p)
                {
                        *p = '\0';
-                       kconf = find_conf_by_address(p+1, NULL, NULL, ip, CONF_KILL, aftype, iconf->info.name, NULL);
+                       kconf = find_conf_by_address(p+1, NULL, NULL, NULL, CONF_KILL, aftype, iconf->info.name, NULL);
                        *p = '@';
                }
                else
-                       kconf = find_conf_by_address(iconf->info.name, NULL, NULL, ip, CONF_KILL, aftype, vuser, NULL);
+                       kconf = find_conf_by_address(iconf->info.name, NULL, NULL, NULL, CONF_KILL, aftype, vuser, NULL);
 
                if(kconf)
                        return kconf;
+
+               /* everything else checks real hosts, if they're kline_spoof_ip we're done */
+               if(IsConfKlineSpoof(iconf))
+                       return iconf;
        }
 
+       /* Find the best K-line... -A1kmm */
+       kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, user, NULL);
+
+       /* If they are K-lined, return the K-line */
+       if(kconf)
+               return kconf;
+
        /* if no_tilde, check the username without tilde against klines too
         * -- jilles */
        if(user != vuser)
@@ -422,16 +424,6 @@ find_address_conf(const char *host, const char *sockhost, const char *user,
                        return kconf;
        }
 
-#ifdef RB_IPV6
-       if(ip != NULL && ip->sa_family == AF_INET6 &&
-                       rb_ipv4_from_ipv6((const struct sockaddr_in6 *)(const void *)ip, &ip4))
-       {
-               kconf = find_conf_by_address(NULL, NULL, NULL, (struct sockaddr *)&ip4, CONF_KILL, AF_INET, vuser, NULL);
-               if(kconf)
-                       return kconf;
-       }
-#endif /* RB_IPV6 */
-
        return iconf;
 }
 
@@ -444,9 +436,7 @@ struct ConfItem *
 find_dline(struct sockaddr *addr, int aftype)
 {
        struct ConfItem *aconf;
-#ifdef RB_IPV6
        struct sockaddr_in addr2;
-#endif
 
        aconf = find_conf_by_address(NULL, NULL, NULL, addr, CONF_EXEMPTDLINE | 1, aftype, NULL, NULL);
        if(aconf)
@@ -454,7 +444,6 @@ find_dline(struct sockaddr *addr, int aftype)
        aconf = find_conf_by_address(NULL, NULL, NULL, addr, CONF_DLINE | 1, aftype, NULL, NULL);
        if(aconf)
                return aconf;
-#ifdef RB_IPV6
        if(addr->sa_family == AF_INET6 &&
                        rb_ipv4_from_ipv6((const struct sockaddr_in6 *)(const void *)addr, &addr2))
        {
@@ -462,7 +451,6 @@ find_dline(struct sockaddr *addr, int aftype)
                if(aconf)
                        return aconf;
        }
-#endif
        return NULL;
 }
 
@@ -482,15 +470,12 @@ find_exact_conf_by_address(const char *address, int type, const char *username)
        if(address == NULL)
                address = "/NOMATCH!/";
        masktype = parse_netmask(address, &addr, &bits);
-#ifdef RB_IPV6
        if(masktype == HM_IPV6)
        {
                /* We have to do this, since we do not re-hash for every bit -A1kmm. */
                hv = hash_ipv6((struct sockaddr *)&addr, bits - bits % 16);
        }
-       else
-#endif
-       if(masktype == HM_IPV4)
+       else if(masktype == HM_IPV4)
        {
                /* We have to do this, since we do not re-hash for every bit -A1kmm. */
                hv = hash_ipv4((struct sockaddr *)&addr, bits - bits % 8);
@@ -531,28 +516,25 @@ void
 add_conf_by_address(const char *address, int type, const char *username, const char *auth_user, struct ConfItem *aconf)
 {
        static unsigned long prec_value = 0xFFFFFFFF;
-       int masktype, bits;
+       int bits;
        unsigned long hv;
        struct AddressRec *arec;
 
        if(address == NULL)
                address = "/NOMATCH!/";
        arec = rb_malloc(sizeof(struct AddressRec));
-       masktype = parse_netmask(address, &arec->Mask.ipa.addr, &bits);
-       arec->Mask.ipa.bits = bits;
-       arec->masktype = masktype;
-#ifdef RB_IPV6
-       if(masktype == HM_IPV6)
+       arec->masktype = parse_netmask(address, &arec->Mask.ipa.addr, &bits);
+       if(arec->masktype == HM_IPV6)
        {
+               arec->Mask.ipa.bits = bits;
                /* We have to do this, since we do not re-hash for every bit -A1kmm. */
                bits -= bits % 16;
                arec->next = atable[(hv = hash_ipv6((struct sockaddr *)&arec->Mask.ipa.addr, bits))];
                atable[hv] = arec;
        }
-       else
-#endif
-       if(masktype == HM_IPV4)
+       else if(arec->masktype == HM_IPV4)
        {
+               arec->Mask.ipa.bits = bits;
                /* We have to do this, since we do not re-hash for every bit -A1kmm. */
                bits -= bits % 8;
                arec->next = atable[(hv = hash_ipv4((struct sockaddr *)&arec->Mask.ipa.addr, bits))];
@@ -585,16 +567,13 @@ delete_one_address_conf(const char *address, struct ConfItem *aconf)
        struct AddressRec *arec, *arecl = NULL;
        struct rb_sockaddr_storage addr;
        masktype = parse_netmask(address, &addr, &bits);
-#ifdef RB_IPV6
        if(masktype == HM_IPV6)
        {
                /* We have to do this, since we do not re-hash for every bit -A1kmm. */
                bits -= bits % 16;
                hv = hash_ipv6((struct sockaddr *)&addr, bits);
        }
-       else
-#endif
-       if(masktype == HM_IPV4)
+       else if(masktype == HM_IPV4)
        {
                /* We have to do this, since we do not re-hash for every bit -A1kmm. */
                bits -= bits % 8;