summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/socket.h1
-rw-r--r--src/cmd_oper.cpp4
-rw-r--r--src/socket.cpp48
-rw-r--r--src/wildcard.cpp2
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@<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)
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);
}