#include "client.h"
#include "ircd.h"
#include "match.h"
+#include "s_conf.h"
#include "s_assert.h"
/*
}
}
+/* Reorder runs of [?*] in mask to the form ``**...??...'' */
+void
+match_arrange_stars(char *mask)
+{
+ char *swap = NULL;
+
+ for (char *p = mask; *p != '\0'; p++)
+ {
+ switch (*p)
+ {
+ case '*':
+ if (swap == NULL) break;
+ *swap++ = '*';
+ *p = '?';
+ break;
+ case '?':
+ if (swap == NULL) swap = p;
+ break;
+ default:
+ swap = NULL;
+ break;
+ }
+ }
+}
+
/** Check a mask against a mask.
* This test checks using traditional IRC wildcards only: '*' means
* match zero or more characters of any type; '?' means match exactly
* @param[in] name New wildcard-containing mask.
* @return 1 if \a name is equal to or more specific than \a mask, 0 otherwise.
*/
-int mask_match(const char *mask, const char *name)
+int mask_match(const char *mask_, const char *name)
{
+ static char mask[BUFSIZE];
const char *m = mask, *n = name;
const char *m_tmp = mask, *n_tmp = name;
+ size_t len;
int star_p;
- s_assert(mask != NULL);
+ s_assert(mask_ != NULL);
s_assert(name != NULL);
+ len = rb_strlcpy(mask, mask_, sizeof mask);
+ s_assert(len < sizeof mask);
+ (void) len; /* for NDEBUG */
+
+ match_arrange_stars(mask);
+
for (;;)
{
switch (*m)
else if (*m == '?')
{
/* changed for mask_match() */
+ while (star_p && *n == '*') n++;
if (*n == '*' || !*n)
goto backtrack;
n++;
void matchset_for_client(struct Client *who, struct matchset *m)
{
+ bool hide_ip = IsIPSpoof(who) || (!ConfigChannel.ip_bans_through_vhost && IsDynSpoof(who));
unsigned hostn = 0;
unsigned ipn = 0;
sprintf(m->host[hostn++], "%s!%s@%s", who->name, who->username, who->host);
- if (!IsIPSpoof(who))
+ if (!hide_ip)
{
sprintf(m->ip[ipn++], "%s!%s@%s", who->name, who->username, who->sockhost);
}
sprintf(m->host[hostn++], "%s!%s@%s", who->name, who->username, who->localClient->mangledhost);
}
}
- if (!IsIPSpoof(who) && GET_SS_FAMILY(&who->localClient->ip) == AF_INET6 &&
+ if (!hide_ip && GET_SS_FAMILY(&who->localClient->ip) == AF_INET6 &&
rb_ipv4_from_ipv6((const struct sockaddr_in6 *)&who->localClient->ip, &ip4))
{
- int n = sprintf(m->ip[ipn++], "%s!%s@", who->name, who->username);
+ int n = sprintf(m->ip[ipn], "%s!%s@", who->name, who->username);
rb_inet_ntop_sock((struct sockaddr *)&ip4,
m->ip[ipn] + n, sizeof m->ip[ipn] - n);
+ ipn++;
}
for (int i = hostn; i < ARRAY_SIZE(m->host); i++)