addr->in6[cpos + jj] = 0;
}
} else if (dot) {
- unsigned int ip4;
+ uint32_t ip4;
pos = irc_pton_ip4(input, bits, &ip4);
if (pos) {
addr->in6[5] = htons(65535);
int
irccasecmp(const char *stra, const char *strb) {
+ if (!stra)
+ return -1;
+ if (!strb)
+ return 1;
while (*stra && (tolower(*stra) == tolower(*strb)))
stra++, strb++;
return tolower(*stra) - tolower(*strb);
return NULL;
}
+char *
+ircstrlower(char *str) {
+ size_t ii;
+ for (ii = 0; str[ii] != '\0'; ++ii)
+ str[ii] = tolower(str[ii]);
+ return str;
+}
+
int
split_line(char *line, int irc_colon, int argv_size, char *argv[])
{
return 0;
m = m_tmp;
n = ++n_tmp;
+ if (!*n)
+ return 0;
break;
case '\\':
m++;
}
int
-user_matches_glob(struct userNode *user, const char *orig_glob, int flags)
+user_matches_glob(struct userNode *user, const char *orig_glob, int flags, int shared)
{
- char *glob, *marker;
+ char *tmpglob, *glob, *marker;
+ char exttype = 0;
+ int extreverse = 0, is_extended = 0, match = 0, banned = 0;
+ unsigned int count, n;
+ struct modeNode *mn;
+ struct chanNode *channel;
+ struct banNode *ban;
/* Make a writable copy of the glob */
glob = alloca(strlen(orig_glob)+1);
strcpy(glob, orig_glob);
+
+ /* Extended bans */
+ tmpglob = alloca(strlen(orig_glob)+1);
+ tmpglob = strdup(orig_glob);
+
+ if (*tmpglob == '~') {
+ tmpglob++; /* get rid of the ~ */
+
+ if (*tmpglob == '!') {
+ extreverse = 1;
+ tmpglob++; /* get rid of the ! */
+ }
+
+ exttype = *tmpglob;
+ tmpglob++; /* get rid of the type */
+
+ if (*tmpglob == ':') {
+ is_extended = 1;
+ tmpglob++; /* get rid of the : */
+ glob = strdup(tmpglob);
+ }
+ }
+
+ if (is_extended) {
+ log_module(MAIN_LOG, LOG_DEBUG, "Extended ban. T (%c) R (%d) M (%s)", exttype, extreverse, glob);
+ switch (exttype) {
+ case 'a': // account
+ if (user->handle_info) {
+ if (extreverse) {
+ if (0 != strcasecmp(glob, user->handle_info->handle))
+ return 1;
+ } else {
+ if (0 == strcasecmp(glob, user->handle_info->handle))
+ return 1;
+ }
+ } else {
+ if (extreverse)
+ return 1;
+ }
+ return match_ircglob(user->hostname, glob);
+ case 'c': // another channel
+ if (!strstr(glob, "#"))
+ return -1;
+
+ if (extreverse) {
+ for (n=count=0; n<user->channels.used; n++) {
+ mn = user->channels.list[n];
+ match = 0;
+
+ if (*glob == '#') {
+ if (0 == strcasecmp(glob, mn->channel->name))
+ match = 1;
+ } else {
+ if (0 == strcasecmp(glob+1, mn->channel->name)) {
+ if ((*glob == '@') && (mn->modes & MODE_CHANOP))
+ match = 1;
+ else if ((*glob == '%') && (mn->modes & MODE_HALFOP))
+ match = 1;
+ else if ((*glob == '+') && (mn->modes & MODE_VOICE))
+ match = 1;
+ }
+ }
+
+ if (match == 0)
+ banned = 1;
+ else {
+ banned = 0;
+ break;
+ }
+ }
+ } else {
+ for (n=count=0; n<user->channels.used; n++) {
+ mn = user->channels.list[n];
+ match = 0;
+
+ if (*glob == '#') {
+ if (0 == strcasecmp(glob, mn->channel->name))
+ match = 1;
+ } else {
+ if (0 == strcasecmp(glob+1, mn->channel->name)) {
+ if ((*glob == '@') && (mn->modes & MODE_CHANOP))
+ match = 1;
+ else if ((*glob == '%') && (mn->modes & MODE_HALFOP))
+ match = 1;
+ else if ((*glob == '+') && (mn->modes & MODE_VOICE))
+ match = 1;
+ }
+ }
+
+ if (match == 1)
+ banned = 1;
+ }
+ }
+
+ if (banned)
+ return 1;
+ else
+ return match_ircglob(user->hostname, glob);
+ case 'j':
+ if (shared == 0) {
+ if (*glob != '#')
+ return -1;
+ if ((channel = GetChannel(glob))) {
+ for (n = 0; n < channel->banlist.used; n++) {
+ ban = channel->banlist.list[n];
+ if (user_matches_glob(user, ban->ban, flags, 1))
+ return 1;
+ }
+ }
+ }
+ return match_ircglob(user->hostname, glob);
+ case 'n': /* this is handled ircd side */
+ return match_ircglob(user->hostname, glob);
+ case 'q': /* this is handled ircd side */
+ return match_ircglob(user->hostname, glob);
+ case 't': /* this is handled ircd side */
+ return match_ircglob(user->hostname, glob);
+ case 'R': /* this is handled ircd side */
+ return match_ircglob(user->hostname, glob);
+ case 'm': // mute by mark
+ if(user->mark && !strcmp(glob, user->mark))
+ return true;
+ else
+ return false;
+
+ case 'M': // mute by mark unless authed
+ return false; // can never match a logged in user
+
+ default:
+ return -1;
+ }
+ }
+
/* Check the nick, if it's present */
if (flags & MATCH_USENICK) {
if (!(marker = strchr(glob, '!'))) {
/* If only matching the visible hostnames, bail early. */
if ((flags & MATCH_VISIBLE) && IsHiddenHost(user)
- && (IsFakeHost(user) || (hidden_host_suffix && user->handle_info)))
+ && (IsFakeHost(user) || (hidden_host_suffix && user->handle_info) ||
+ user->crypthost || user->cryptip))
return 0;
/* If it might be an IP glob, test that. */
if (!glob[strspn(glob, "0123456789./*?")]
int
is_ircmask(const char *text)
{
+ char *tmptext;
+
+ if (*text == '~') {
+ tmptext = alloca(strlen(text)+1);
+ tmptext = strdup(text);
+
+ tmptext++; /* get rid of the ~ */
+
+ if (*tmptext == '!')
+ tmptext++; /* get rid of the ! if it exists */
+
+ tmptext++; /* get rid of the ext ban type */
+
+ if (*tmptext == ':') {
+ tmptext++; /* get rid of the : */
+ while (*tmptext && !isspace((char)*tmptext))
+ tmptext++; /* get rid of the rest */
+ return !*tmptext;
+ }
+ }
+
while (*text && (isalnum((char)*text) || strchr("-_[]|\\`^{}?*", *text)))
text++;
if (*text++ != '!')
/* process the string, resetting the count if we find a unit character */
while ((c = *interval++)) {
- if (isdigit((int)c)) {
- partial = partial*10 + c - '0';
- } else {
- seconds += TypeLength(c) * partial;
- partial = 0;
- }
+ if (isdigit((int)c)) {
+ partial = partial*10 + c - '0';
+ } else if (strchr("yMwdhms", c)) {
+ seconds += TypeLength(c) * partial;
+ partial = 0;
+ } else {
+ return 0;
+ }
}
/* assume the last chunk is seconds (the normal case) */
return seconds + partial;