]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Support CIDR, CIDR zline, /oper and CIDR <connect> tags. NOTE: With CIDR oper, ident...
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>
Sun, 6 Aug 2006 16:09:29 +0000 (16:09 +0000)
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>
Sun, 6 Aug 2006 16:09:29 +0000 (16:09 +0000)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@4732 e03df62e-2008-0410-955e-edbf42e46eb7

include/socket.h
include/wildcard.h
src/cmd_oper.cpp
src/commands.cpp
src/helperfuncs.cpp
src/inspircd.cpp
src/modules/extra/m_sqloper.cpp
src/socket.cpp
src/users.cpp
src/wildcard.cpp
src/xline.cpp

index 399f84397f922703d7817d6aa5a2a5bfcf4c47ba..2dcece9060421af88ff40ae4a053a9ea185b660f 100644 (file)
@@ -50,6 +50,7 @@ typedef struct in_addr      insp_inaddr;
 #endif
 
 bool MatchCIDRBits(unsigned char* address, unsigned char* mask, unsigned int mask_bits);
+bool MatchCIDR(const char* address, const char* cidr_mask);
 
 const char* insp_ntoa(insp_inaddr n);
 int insp_aton(const char* a, insp_inaddr* n);
index 936bd9e23589984f8f01e2d1d49ff2d81c53d006..02bc6342c92f3b8c2aa490c97afaaebefc2d30d6 100644 (file)
@@ -17,4 +17,5 @@
 #include "inspircd_config.h"
 
 bool match(const char* str, const char* mask);
+bool match(const char *str, const char *mask, bool use_cidr_match);
 
index 310c9126604b51b52f7ea66700f69cd83b5d8fb3..fd71b8694916ea3fd1545771cdc2a6d0e8fcba2e 100644 (file)
@@ -43,14 +43,14 @@ extern ModuleList modules;
 extern FactoryList factory;
 extern time_t TIME;
 
-bool OneOfMatches(const char* host, const char* hostlist)
+bool OneOfMatches(const char* host, const char* ip, const char* hostlist)
 {
        std::stringstream hl(hostlist);
        std::string xhost;
        while (hl >> xhost)
        {
                log(DEBUG,"Oper: Matching host %s",xhost.c_str());
-               if (match(host,xhost.c_str()))
+               if (match(host,xhost.c_str()) || match(ip,xhost.c_str(),true))
                {
                        return true;
                }
@@ -79,7 +79,7 @@ void cmd_oper::Handle (const char** parameters, int pcnt, userrec *user)
                Config->ConfValue(Config->config_data, "oper", "type", i, OperType, MAXBUF);
                Config->ConfValue(Config->config_data, "oper", "host", i, HostName, MAXBUF);
 
-               if ((!strcmp(LoginName,parameters[0])) && (!operstrcmp(Password,parameters[1])) && (OneOfMatches(TheHost,HostName)))
+               if ((!strcmp(LoginName,parameters[0])) && (!operstrcmp(Password,parameters[1])) && (OneOfMatches(TheHost,user->GetIPString(),HostName)))
                {
                        fail2 = true;
                        for (j =0; j < Config->ConfValueEnum(Config->config_data, "type"); j++)
index 427633ef4663e8e81554ff40cecfb7ac8fdd533b..2e4ae0d8f29bfc800046e1c112ac28090e0aec34 100644 (file)
@@ -239,7 +239,7 @@ bool ip_matches_everyone(const std::string &ip, userrec* user)
        
        for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++)
        {
-               if (match(u->second->GetIPString(),ip.c_str()))
+               if (match(u->second->GetIPString(),ip.c_str(),true))
                        matches++;
        }
        
index 9ba9d7b3937e852bbe5b895f7fb0ac5252959c0d..1ebf890087dc9f036a2f2244639871f0c3f9e7e2 100644 (file)
@@ -1405,7 +1405,7 @@ ConnectClass GetClass(userrec *user)
 {
        for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++)
        {
-               if ((match(user->GetIPString(),i->host.c_str())) || (match(user->host,i->host.c_str())))
+               if ((match(user->GetIPString(),i->host.c_str(),true)) || (match(user->host,i->host.c_str())))
                {
                        return *i;
                }
index 09cd74d6987a915621a71d1a0f67839950378b32..a2b4e0d92e2c1e7ea67917c9a3d06196c5787752 100644 (file)
@@ -940,13 +940,13 @@ int InspIRCd::Run()
 
 int main(int argc, char** argv)
 {
-
-       unsigned char addr[] = {0xCC,0xAA,0xCC,0xAA};
-       unsigned char mask[] = {0xCC,0xAA,0xC0,0xAA};
-
-       printf("%d",MatchCIDRBits(addr, mask, 20));
-
-       exit(0);
+       /* This is a MatchCIDR() test suite -
+       printf("Should be 0: %d\n",MatchCIDR("127.0.0.1","1.2.3.4/8"));
+       printf("Should be 1: %d\n",MatchCIDR("127.0.0.1","127.0.0.0/8"));
+       printf("Should be 1: %d\n",MatchCIDR("127.0.0.1","127.0.0.0/18"));
+       printf("Should be 0: %d\n",MatchCIDR("3ffe::0","2fc9::0/16"));
+       printf("Should be 1: %d\n",MatchCIDR("3ffe:1:3::0", "3ffe:1::0/32"));
+       exit(0); */
 
        try
        {
index 191753e6623b27630cc3608f33f9540723bc6eef..81f22eca60c92f241a3b98da571f94b5410ddc90 100644 (file)
@@ -223,10 +223,10 @@ public:
                        std::string hostname(user->ident);
                        hostname.append("@").append(user->host);
                                                        
-                       if((tname == type) && OneOfMatches(hostname.c_str(), pattern.c_str()))
+                       if((tname == type) && OneOfMatches(hostname.c_str(), user->GetIPString(), pattern.c_str()))
                        {
                                /* Opertype and host match, looks like this is it. */
-                               log(DEBUG, "Host (%s matched %s) and type (%s)", pattern.c_str(), hostname.c_str(), type.c_str());
+                               log(DEBUG, "Host (%s matched %s OR %s) and type (%s)", pattern.c_str(), hostname.c_str(), user->GetIPString(), type.c_str());
                                
                                std::string operhost = Conf.ReadValue("type", "host", j);
                                                        
index 41c4fd1ca60f5f4d2ba532220c307175978ebd31..14fe580adf804e366bae87eb9a8d2e12bc18ec5d 100644 (file)
@@ -41,8 +41,8 @@ char inverted_bits[8] = { 0x00, /* 00000000 - 0 bits */
 
 bool MatchCIDRBits(unsigned char* address, unsigned char* mask, unsigned int mask_bits)
 {
-       unsigned int modulus = mask_bits  & 0x07; /* Number of whole bytes in the mask */
-       unsigned int divisor = mask_bits >> 0x04; /* Remaining bits in the mask after whole bytes are dealt with */
+       unsigned int modulus = mask_bits % 8; /* Number of whole bytes in the mask */
+       unsigned int divisor = mask_bits / 8; /* Remaining bits in the mask after whole bytes are dealt with */
 
        /* First compare the whole bytes, if they dont match, return false */
        if (memcmp(address, mask, divisor))
@@ -58,6 +58,66 @@ bool MatchCIDRBits(unsigned char* address, unsigned char* mask, unsigned int mas
        return true;
 }
 
+bool MatchCIDR(const char* address, const char* cidr_mask)
+{
+       unsigned char addr_raw[16];
+       unsigned char mask_raw[16];
+       unsigned int bits = 0;
+       char* mask = strdup(cidr_mask);
+
+       in_addr  address_in4;
+       in_addr  mask_in4;
+
+       char* bits_chars = strchr(mask,'/');
+
+       if (bits_chars)
+       {
+               bits = atoi(bits_chars + 1);
+               *bits_chars = 0;
+       }
+
+#ifdef SUPPORT_IP6LINKS
+       in6_addr address_in6;
+       in6_addr mask_in6;
+
+       if (inet_pton(AF_INET6, address, &address_in6) > 0)
+       {
+               if (inet_pton(AF_INET6, mask, &mask_in6) > 0)
+               {
+                       memcpy(&addr_raw, &address_in6.s6_addr, 16);
+                       memcpy(&mask_raw, &mask_in6.s6_addr, 16);
+               }
+               else
+               {
+                       free(mask);
+                       return false;
+               }
+       }
+       else
+#endif
+       if (inet_pton(AF_INET, address, &address_in4) > 0)
+       {
+               if (inet_pton(AF_INET, mask, &mask_in4) > 0)
+               {
+                       memcpy(&addr_raw, &address_in4.s_addr, 4);
+                       memcpy(&mask_raw, &mask_in4.s_addr, 4);
+               }
+               else
+               {
+                       free(mask);
+                       return false;
+               }
+       }
+       else
+       {
+               free(mask);
+               return false;
+       }
+
+       free(mask);
+       return MatchCIDRBits(addr_raw, mask_raw, bits);
+}
+
 /** This will bind a socket to a port. It works for UDP/TCP.
  * It can only bind to IP addresses, if you wish to bind to hostnames
  * you should first resolve them using class 'Resolver'.
index 7ed5e2fd6bef3008ba774936a252a395ff855dcf..c02dbd4ab171e63dae228ef1c0f1ba49530bd69a 100644 (file)
@@ -844,7 +844,7 @@ void AddClient(int socket, int port, bool iscached, insp_inaddr ip)
 
        for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++)
        {
-               if ((i->type == CC_ALLOW) && (match(ipaddr,i->host.c_str())))
+               if ((i->type == CC_ALLOW) && (match(ipaddr,i->host.c_str(),true)))
                {
                        class_regtimeout = (unsigned long)i->registration_timeout;
                        class_flood = i->flood;
index aa9f52102d66e9600d0fcfa1371fe68d62c86647..3b4554f0fe5226215a76c93de2ef48ca91480b9c 100644 (file)
@@ -83,3 +83,10 @@ bool match(const char *str, const char *mask)
        return !*wild;
 }
 
+/* Overloaded function that has the option of using cidr */
+bool match(const char *str, const char *mask, bool use_cidr_match)
+{
+       if (use_cidr_match && MatchCIDR(str, mask))
+               return true;
+       return match(str, mask);
+}
index 7970f977efcf1745ff3f9ed96f4db8c1b2564396..32619b18c181476a0c980185ae78ae1e895ba788 100644 (file)
@@ -558,10 +558,10 @@ char* matches_zline(const char* ipaddr)
        if ((zlines.empty()) && (pzlines.empty()))
                return NULL;
        for (std::vector<ZLine>::iterator i = zlines.begin(); i != zlines.end(); i++)
-               if (match(ipaddr,i->ipaddr))
+               if (match(ipaddr,i->ipaddr,true))
                        return i->reason;
        for (std::vector<ZLine>::iterator i = pzlines.begin(); i != pzlines.end(); i++)
-               if (match(ipaddr,i->ipaddr))
+               if (match(ipaddr,i->ipaddr,true))
                        return i->reason;
        return NULL;
 }