Req: EXTBAN channel ban synergy

These are old archives. They are kept for historic purposes only.
Post Reply
sdamon
Posts: 46
Joined: Tue Jun 07, 2005 7:28 am

Req: EXTBAN channel ban synergy

Post by sdamon »

This is conceptually simple.
The module would provide an EXTBAN, that when given a second channel as a parameter, would enforce that channel's bans in the channel where the EXTBAN was set. This would be incredibly useful for projects with large numbers of channels to rapidly ban spammers from all their channels, or add a ban exemption of a group of users to all their channels.

not knowing the internals of unreal, I cannot say for certain how tough this would be, but I can't imagine it would be too difficult.
katsklaw
Posts: 1124
Joined: Sun Apr 18, 2004 5:06 pm
Contact:

Re: Req: EXTBAN channel ban synergy

Post by katsklaw »

I don't see it as difficult either except that ban has multiple parameters already. Perhaps the EXTBAN syntax can be #chan,#chan2,#chan3 instead of #chan #chan2 #chan3. That way we aren't looking for the pound sign(#) in the ban reason but parsing the channel the same as JOIN and PART already do.

Where it becomes tricky is where you look at user permissions, does the user have authority to ban in all channels?
sdamon
Posts: 46
Joined: Tue Jun 07, 2005 7:28 am

Re: Req: EXTBAN channel ban synergy

Post by sdamon »

The ban instated in the target channel (the one targeted by the extban) would not need to have the authority to ban in the host channel, as the person who set the extban would be the person responsible for the bans in the host channel.

I also don't see a need to list multiple channels in the extban. for instance if the extban mode name was 'S', one would check against 2 channels by 'MODE #host-channel +bb ~S:#first-other-channel ~S:#second-other-channel'.
katsklaw
Posts: 1124
Joined: Sun Apr 18, 2004 5:06 pm
Contact:

Re: Req: EXTBAN channel ban synergy

Post by katsklaw »

checking permissions is almost always a good idea. Just because your channels on your network will be run by the same person, doesn't mean that is always the case everywhere. It's too easy to imagine a person that has access in #chan1 not having access on #chan2.

Anyway, good luck getting this coded.
sdamon
Posts: 46
Joined: Tue Jun 07, 2005 7:28 am

Re: Req: EXTBAN channel ban synergy

Post by sdamon »

Checking permissions is an impossible task anyways.

Take #x, which has 10 users, 2 of which are ops (@Bill and @Ted). Now, @Ted bans bogusone!*@*.aol.com, then goes for a sandwich. While at Subway, @Ted's power goes out. The ban stays in effect. when Ted gets back, he is a normal user, but the ban is still listed as being set by him.

lets add #y. @GrimReaper sets an extban to mirror all the bans from #x. it wouldn't matter if Ted, who set a ban in #x, is not oped in #y, cause it doesn't matter if Ted is oped in #x for his ban to still be effective. If Ted went crazy and set a ban for GrimReaper!*@* in #x, then its incumbent on him to set an exempt in his own channel to prevent the ban from booting him.

the only way permissions can be checked is if the extban is handled by services, where there is persistent identity. and that is well beyond the scope of the IRCD's concern.
Stealth
Head of Support
Posts: 2086
Joined: Tue Jun 15, 2004 8:50 pm
Location: Chino Hills, CA, US
Contact:

Re: Req: EXTBAN channel ban synergy

Post by Stealth »

Sounds like all you need is (pseudo code, someone wouldn't have too much trouble making it a module):

Code: Select all

Override JOIN
join {
  while findEXTban(S) {
    if (isbanned(otherchan)) { sendtoone ERR_ISBANNED; return 1; }
  }
}
EDIT:
As far as permissions go, I don't see a need to check permissions across channels. Obviously if an op wanted to enforce the bans of another channel, it's up to that op and the rest of the channel's staff to trust the judgment of the target channel's staff. This applies to any other cross-channel banning (+b/+e ~c).
katsklaw
Posts: 1124
Joined: Sun Apr 18, 2004 5:06 pm
Contact:

Re: Req: EXTBAN channel ban synergy

Post by katsklaw »

Stealth wrote: As far as permissions go, I don't see a need to check permissions across channels. Obviously if an op wanted to enforce the bans of another channel, it's up to that op and the rest of the channel's staff to trust the judgment of the target channel's staff. This applies to any other cross-channel banning (+b/+e ~c).
Sure, not a problem .. get this up and running on your network Stealth and I'll com over, register a channel then ban all your ops from my channel using this :lol:

Permissions are more important than you think.
sdamon
Posts: 46
Joined: Tue Jun 07, 2005 7:28 am

Re: Req: EXTBAN channel ban synergy

Post by sdamon »

oh you can already ban all ops from stealth's channel by 'MODE #your_channel +b ~c:@#stealths_channel'.

what the extban would do is just copy another channels ban list to yours (well not copy, but its conceptual1).
Stealth
Head of Support
Posts: 2086
Joined: Tue Jun 15, 2004 8:50 pm
Location: Chino Hills, CA, US
Contact:

Re: Req: EXTBAN channel ban synergy

Post by Stealth »

katsklaw wrote:Sure, not a problem .. get this up and running on your network Stealth and I'll com over, register a channel then ban all your ops from my channel using this :lol:

Permissions are more important than you think.
I don't see how this would ban all my ops considering the original module is for syncing banlists, which would mean ops would need to be banned from the original channel anyway. ~c is used for banning people in other channels, and as sdamon pointed out can accept a rank parameter. If you're referring to banning opers from channels, you can use "+b ~c:#opers" (personally I wouldn't care if you did such, as my network is open for anyone's use and I monitor connects/disconnects for unwanted activity).

EDIT: However, if you're channel is #chan1 and you set "+b ~S:#chan2" an op in #chan2 can ban one of your ops (or all of them because they're dicks), but that all comes back to users needing to trust the ops of the other channel. This is where the need to have services comes into play, so people can regain control of their banlist by using CS Invite to override the bans.
katsklaw
Posts: 1124
Joined: Sun Apr 18, 2004 5:06 pm
Contact:

Re: Req: EXTBAN channel ban synergy

Post by katsklaw »

oh ok, my bad .. I was thinking I ban chan1's ops from my chan and it propagated forward to their channel. That is where my perm check was coming in. If I understand you now, you are wanting to copy some other channels bans into your own, which is the exact opposite of my previous way of looking at this.
Skizzerz
Posts: 16
Joined: Thu Dec 25, 2008 1:39 am

Re: Req: EXTBAN channel ban synergy

Post by Skizzerz »

Well, I made one. I'm sure it isn't the most efficient code out there, but it works at least. Have not tested on a multi-server network though, but I don't think that matters. That being said, I have tested this to ensure that it works properly, but there might be a bug or two in corner cases. If this happens, please let me know so I can fix it.

Module "features":
  • adds ~S extended ban type, in the format ~S:#channel
  • a user trying to do anything in the channel the ~S ban is set in is also checked against the other channel
  • no channel privileges are checked, so you need to trust the operators of the channel you are syncing with to not go rouge and ban your entire channel
  • works on all types of bans, including normal +b, quiets, etc.
  • an invite or local channel exemption overrides the synced bans, as expected
  • this only goes one level down. Meaning, if #chan1 sets +b ~S:#chan2, and #chan2 sets +b ~S:#chan3, the bans from #chan3 will NOT affect #chan1 (this also breaks potential endless loop cases where two channels sync with each other)
  • multiple ~S bans in a channel are fine
Code:

Code: Select all

/*
 * This module implements an extended bantype to sync one channel's ban list
 * with anothers. It is up to the channel staff on the channel this mode is used
 * to trust the channel staff of the channel they are syncing to, permissions
 * are not checked by this module.
 * /mode #chan1 +b ~S:#chan2 will make it so that everyone on #chan1 is also
 * checked against #chan2's banlist as well as their own.
 * 
 * Module copyright (c) 2009 Ryan Schmidt <[email protected]>
 * Licensed under the Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
 * (CC-BY-NC-SA). See more details here: http://creativecommons.org/licenses/by-nc-sa/3.0/
 */

#include "config.h"
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "msg.h"
#include "proto.h"
#include "channel.h"
#include <time.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <io.h>
#include <version.h>
#endif
#ifdef STRIPBADWORDS
#include "badwords.h"
#endif
#include <fcntl.h>
#include "h.h"

ModuleHeader MOD_HEADER(m_bansync) = {
	"m_bansync",
	"v1.0",
	"Sync channel banlists via extban ~S",
	"3.2-b8-1",
	NULL
};

#define BSBANCHAR 'S'
char *bs_param(char *param);
int bs_banned(aClient *sptr, aChannel *chptr, char *ban, int chktype);
Extban *bsExtBan;
typedef struct bs_recurse BsRecurse;
struct bs_recurse {
	char *chname;
	int recurse;
};

DLLFUNC int MOD_INIT(m_bansync)(ModuleInfo *modinfo) {
	ModuleSetOptions(modinfo->handle, MOD_OPT_PERM);
	
	ExtbanInfo bsInfo;
	memset(&bsInfo, 0, sizeof(ExtbanInfo));
	bsInfo.flag = BSBANCHAR;
	bsInfo.conv_param = bs_param;
	bsInfo.is_banned = bs_banned;
	bsExtBan = ExtbanAdd(modinfo->handle, bsInfo);
	
	return MOD_SUCCESS;
}

DLLFUNC int MOD_LOAD(m_bansync)(int module_load) {
	return MOD_SUCCESS;
}

DLLFUNC int MOD_UNLOAD(m_bansync)(int module_unload) {
	return MOD_FAILED;
}

char *bs_param(char *param) {
	if(match("~?:#*", param) || strchr(param, ',') != NULL) {
		return NULL;
	}
	return param;
}

int bs_banned(aClient *sptr, aChannel *chptr, char *ban, int chktype) {
	char banstr[64], *chantok;
	aChannel *chan;
	Ban *banned;
	static BsRecurse recurse = {
		"dummy", //dummy value to prevent segfaults
		1
	};
	
	// recurse check, only sync with the channel at not to channels that that channel is synced to
	if(strcmp(recurse.chname, chptr->chname) == 0 && recurse.recurse == 0) {
		recurse.recurse = 1;
		return 0;
	}
	strncpy(banstr, ban, sizeof(banstr));
	// ignore the ~S part
	(void) strtok(banstr, ":");
	// grab the channel
	chantok = strtok(NULL, ":");
	if(!chantok) {
		return 0;
	}
	chan = get_channel(sptr, chantok, !CREATE);
	if(!chan) {
		return 0;
	}
	// chan exists, set the recurse mask and then check for bans on the next channel
	recurse.chname = chantok;
	recurse.recurse = 0;
	banned = is_banned(sptr, chan, chktype);
	if(banned) {
		return 1;
	}
	return 0;
}

Skizzerz
Posts: 16
Joined: Thu Dec 25, 2008 1:39 am

Re: Req: EXTBAN channel ban synergy

Post by Skizzerz »

Got an email a few days back from someone who said that the module didn't work in 3.2.10.1, so here's an update that makes it work (and fixes some other things I didn't like about the original version, but the changes are all mostly stylistic).

Changelog:
  • Module is no longer marked permanent, so you can load/unload it (nb: it doesn't work while unloaded!)
  • Since I'm not sure if the function can be called multiple times at once (e.g. if unrealircd is multithreaded), moved it to using an array to keep track of recursion instead of tracking only a single channel.
  • Relicensed to GPL v2 or any later version to better match license of main UnrealIRCd codebase
  • Switched to using ANSI C style comments, so it theoretically will be accepted by more compilers
Other notes:
  • Tested & works in Unreal 3.2.10.1
  • Supports stacked bans, so e.g. /mode #chan1 +b ~q:~S:#chan2 will cause all users banned or quieted on #chan2 to be quieted on #chan1 (but only if the ban on #chan2 was a generic +b or a quiet; so this would not propagate join or nick bans)
  • DOES NOT SUPPORT BAN EXCEPTIONS OR INVITE EXCEPTIONS (+e or +I). If you try to set +e ~S:#chan2, you will end up exempting everyone that is BANNED on #chan2, which is probably NOT what you want. If enough people seem to want this to be fixed, I'll look into it.
Code:

Code: Select all

/*
 * This module implements an extended bantype to sync one channel's ban list
 * with anothers. It is up to the channel staff on the channel this mode is used
 * to trust the channel staff of the channel they are syncing to, permissions
 * are not checked by this module.
 * /mode #chan1 +b ~S:#chan2 will make it so that everyone on #chan1 is also
 * checked against #chan2's banlist as well as their own.
 *
 * Copyright (c) 2009, 2013 Ryan Schmidt <[email protected]>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "config.h"
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "msg.h"
#include "proto.h"
#include "channel.h"
#include <time.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <io.h>
#include <version.h>
#endif
#ifdef STRIPBADWORDS
#include "badwords.h"
#endif
#include <fcntl.h>
#include "h.h"

ModuleHeader MOD_HEADER(m_bansync) = {
    "m_bansync",
    "v1.1",
    "Sync channel banlists via extban ~S",
    "3.2-b8-1",
    NULL
};

#define BSBANCHAR 'S'
char* bs_param(char* param);
int bs_banned(aClient* sptr, aChannel* chptr, char* ban, int chktype);
Extban* bsExtBan;

int bs_recursion_guard_size;
char** bs_recursion_guard;

DLLFUNC int MOD_INIT(m_bansync)(ModuleInfo* modinfo) {
    ExtbanInfo bsInfo;
    memset(&bsInfo, 0, sizeof(ExtbanInfo));
    bsInfo.flag = BSBANCHAR;
    bsInfo.conv_param = bs_param;
    bsInfo.is_banned = bs_banned;
    bsExtBan = ExtbanAdd(modinfo->handle, bsInfo);

    bs_recursion_guard_size = 32;
    bs_recursion_guard = (char**)calloc(bs_recursion_guard_size, sizeof(char*));

    if (modinfo->handle->errorcode == MODERR_NOERROR)
        return MOD_SUCCESS;
    else
        return MOD_FAILED;
}

DLLFUNC int MOD_LOAD(m_bansync)(int module_load) {
    return MOD_SUCCESS;
}

DLLFUNC int MOD_UNLOAD(m_bansync)(int module_unload) {
    int i;
    for (i = 0; i < bs_recursion_guard_size; ++i) {
        if (bs_recursion_guard[i] != NULL) {
            free(bs_recursion_guard[i]);
        }
    }
    free(bs_recursion_guard);
    bs_recursion_guard = NULL;
    bs_recursion_guard_size = 0;

    ExtbanDel(bsExtBan);

    return MOD_SUCCESS;
}

char* bs_param(char* param) {
    if (match("~?:#*", param) || strchr(param, ',') != NULL) {
        return NULL;
    }

    return param;
}

int bs_banned(aClient* sptr, aChannel* chptr, char* ban, int chktype) {
    char banstr[64], *chantok;
    aChannel* chan;
    Ban* banned;
    int i, havespace;
    char** tmp_recursion_guard;

    /* recurse check, only sync with the channel at not to channels that that channel is synced to */
    for (i = 0; i < bs_recursion_guard_size; ++i) {
        if (bs_recursion_guard[i] != NULL && strcmp(bs_recursion_guard[i], chptr->chname) == 0) {
            return 0;
        }
    }

    strncpy(banstr, ban, sizeof(banstr));

    /* ignore the ~S part */
    (void) strtok(banstr, ":");

    /* grab the channel */
    chantok = strtok(NULL, ":");

    if (!chantok) {
        return 0;
    }

    chan = get_channel(sptr, chantok, !CREATE);

    if (!chan) {
        return 0;
    }

    /* chan exists, add to recursion guard and then check for bans on the next channel */
    havespace = 0;

    for (i = 0; i < bs_recursion_guard_size; ++i) {
        if (bs_recursion_guard[i] == NULL) {
            havespace = 1;
            bs_recursion_guard[i] = strdup(chantok); /* used in core modules, so presumably this is manually defined on non-posix systems */
            break;
        }
    }

    if (!havespace) {
        /* not enough space in the array, so grow it by another 32 channels */
        bs_recursion_guard_size += 32;
        tmp_recursion_guard = (char**)calloc(bs_recursion_guard_size, sizeof(char*));
        memcpy(tmp_recursion_guard, bs_recursion_guard, (bs_recursion_guard_size - 32) * sizeof(char*));
        free(bs_recursion_guard);
        bs_recursion_guard = tmp_recursion_guard;
        bs_recursion_guard[i] = strdup(chantok);
    }

    banned = is_banned(sptr, chan, chktype);

    free(bs_recursion_guard[i]);
    bs_recursion_guard[i] = NULL;

    if (banned) {
        return 1;
    }

    return 0;
}

Syzop
UnrealIRCd head coder
Posts: 2112
Joined: Sat Mar 06, 2004 8:57 pm
Location: .nl
Contact:

Re: Req: EXTBAN channel ban synergy

Post by Syzop »

Maybe submit to modules.unrealircd.org ? :P
Post Reply