diff options
author | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2006-08-06 18:34:39 +0000 |
---|---|---|
committer | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2006-08-06 18:34:39 +0000 |
commit | 3e50e674c3aab0827e62d21e75b828bff0e88da7 (patch) | |
tree | 53c5aae107954aa2342e77cd702debcc6c3d8424 /src/socket.cpp | |
parent | 662253ef6e58a555ce60d26339ab05bf52540677 (diff) |
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
Diffstat (limited to 'src/socket.cpp')
-rw-r--r-- | src/socket.cpp | 48 |
1 files changed, 46 insertions, 2 deletions
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@<mask>/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) |