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 --- src/socket.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) (limited to 'src/socket.cpp') 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) -- cgit v1.2.3