From 3e50e674c3aab0827e62d21e75b828bff0e88da7 Mon Sep 17 00:00:00 2001 From: brain Date: Sun, 6 Aug 2006 18:34:39 +0000 Subject: Allow nick!ident@ and ident@ portions in a CIDR mask if given, use match() without CIDR against that portion. This allows for CIDR operhosts while still matching idents (AND CIDR CHANNEL BANS) git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@4739 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/socket.h | 1 + src/cmd_oper.cpp | 4 +++- src/socket.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- src/wildcard.cpp | 2 +- 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/include/socket.h b/include/socket.h index 2dcece906..38656e238 100644 --- a/include/socket.h +++ b/include/socket.h @@ -51,6 +51,7 @@ typedef struct in_addr insp_inaddr; bool MatchCIDRBits(unsigned char* address, unsigned char* mask, unsigned int mask_bits); bool MatchCIDR(const char* address, const char* cidr_mask); +bool MatchCIDR(const char* address, const char* cidr_mask, bool match_with_username); const char* insp_ntoa(insp_inaddr n); int insp_aton(const char* a, insp_inaddr* n); diff --git a/src/cmd_oper.cpp b/src/cmd_oper.cpp index fd71b8694..f695c44f8 100644 --- a/src/cmd_oper.cpp +++ b/src/cmd_oper.cpp @@ -66,11 +66,13 @@ void cmd_oper::Handle (const char** parameters, int pcnt, userrec *user) char TypeName[MAXBUF]; char HostName[MAXBUF]; char TheHost[MAXBUF]; + char TheIP[MAXBUF]; int j; bool found = false; bool fail2 = false; snprintf(TheHost,MAXBUF,"%s@%s",user->ident,user->host); + snprintf(TheIP, MAXBUF,"%s@%s",user->ident,user->GetIPString()); for (int i = 0; i < Config->ConfValueEnum(Config->config_data, "oper"); i++) { @@ -79,7 +81,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,user->GetIPString(),HostName))) + if ((!strcmp(LoginName,parameters[0])) && (!operstrcmp(Password,parameters[1])) && (OneOfMatches(TheHost,TheIP,HostName))) { fail2 = true; for (j =0; j < Config->ConfValueEnum(Config->config_data, "type"); j++) diff --git a/src/socket.cpp b/src/socket.cpp index b45322c3d..2a33442fe 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -21,6 +21,7 @@ #include "inspstring.h" #include "helperfuncs.h" #include "socketengine.h" +#include "wildcard.h" #include "message.h" extern InspIRCd* ServerInstance; @@ -63,20 +64,63 @@ bool MatchCIDRBits(unsigned char* address, unsigned char* mask, unsigned int mas return true; } +bool MatchCIDR(const char* address, const char* cidr_mask) +{ + return MatchCIDR(address, cidr_mask, false); +} + /* Match CIDR strings, e.g. 127.0.0.1 to 127.0.0.0/8 or 3ffe:1:5:6::8 to 3ffe:1::0/32 * If you have a lot of hosts to match, youre probably better off building your mask once * and then using the lower level MatchCIDRBits directly. */ -bool MatchCIDR(const char* address, const char* cidr_mask) +bool MatchCIDR(const char* address, const char* cidr_mask, bool match_with_username) { unsigned char addr_raw[16]; unsigned char mask_raw[16]; unsigned int bits = 0; - char* mask = strdup(cidr_mask); + char* mask = NULL; + + /* The caller is trying to match ident@/bits. + * Chop off the ident@ portion, use match() on it + * seperately. + */ + if (match_with_username) + { + /* Duplicate the strings, and try to find the position + * of the @ symbol in each */ + char* address_dupe = strdup(address); + char* cidr_dupe = strdup(cidr_mask); + + char* username_mask_pos = strchr(cidr_dupe, '@'); + char* username_addr_pos = strchr(address_dupe, '@'); + + if (username_mask_pos && username_addr_pos) + { + *username_mask_pos = *username_addr_pos = 0; + + bool result = (match(address_dupe, cidr_dupe) && MatchCIDR(username_addr_pos + 1, username_mask_pos + 1)); + + free(address_dupe); + free(cidr_dupe); + + return result; + } + else + { + free(address_dupe); + free(cidr_dupe); + mask = strdup(cidr_mask); + } + } + else + { + mask = strdup(cidr_mask); + } in_addr address_in4; in_addr mask_in4; + char* bits_chars = strchr(mask,'/'); if (bits_chars) diff --git a/src/wildcard.cpp b/src/wildcard.cpp index 3b4554f0f..e626f2aa2 100644 --- a/src/wildcard.cpp +++ b/src/wildcard.cpp @@ -86,7 +86,7 @@ bool match(const char *str, const char *mask) /* 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)) + if (use_cidr_match && MatchCIDR(str, mask, true)) return true; return match(str, mask); } -- cgit v1.2.3