EBMASK capab, to burst BMASK metadata (#354)
This commit is contained in:
parent
a5192806a9
commit
fdd8cad93f
6 changed files with 125 additions and 60 deletions
|
@ -319,6 +319,21 @@ Sets a D:line (IP ban checked directly after accepting connection).
|
||||||
|
|
||||||
The mask must be an IP address or CIDR mask.
|
The mask must be an IP address or CIDR mask.
|
||||||
|
|
||||||
|
EBMASK
|
||||||
|
source: server
|
||||||
|
propagation: broadcast
|
||||||
|
parameters: channelTS, channel, type, space separated "masks ts hostmask" chunks
|
||||||
|
|
||||||
|
If the channelTS in the message is greater (newer) than the current TS of
|
||||||
|
the channel, drop the message and do not propagate it.
|
||||||
|
|
||||||
|
Type is the mode letter of a ban-like mode. In efnet TS6 this is 'b', 'e' or
|
||||||
|
'I'. In charybdis TS6 additionally 'q' is possible.
|
||||||
|
|
||||||
|
Add all the masks and their set at/by to the given list of the channel.
|
||||||
|
|
||||||
|
All ban-like modes must be bursted using this command, not using MODE or TMODE.
|
||||||
|
|
||||||
ECHO
|
ECHO
|
||||||
source: user
|
source: user
|
||||||
parameters: "P"/"N", target, text
|
parameters: "P"/"N", target, text
|
||||||
|
|
|
@ -302,7 +302,7 @@ extern void set_channel_mlock(struct Client *client_p, struct Client *source_p,
|
||||||
|
|
||||||
extern struct ChannelMode chmode_table[256];
|
extern struct ChannelMode chmode_table[256];
|
||||||
|
|
||||||
extern bool add_id(struct Client *source_p, struct Channel *chptr, const char *banid,
|
extern struct Ban * add_id(struct Client *source_p, struct Channel *chptr, const char *banid,
|
||||||
const char *forward, rb_dlink_list * list, long mode_type);
|
const char *forward, rb_dlink_list * list, long mode_type);
|
||||||
|
|
||||||
extern struct Ban * del_id(struct Channel *chptr, const char *banid, rb_dlink_list * list,
|
extern struct Ban * del_id(struct Channel *chptr, const char *banid, rb_dlink_list * list,
|
||||||
|
|
|
@ -92,6 +92,7 @@ extern unsigned int CAP_EUID; /* supports EUID (ext UID + nonencap CHGHOST) */
|
||||||
extern unsigned int CAP_EOPMOD; /* supports EOPMOD (ext +z + ext topic) */
|
extern unsigned int CAP_EOPMOD; /* supports EOPMOD (ext +z + ext topic) */
|
||||||
extern unsigned int CAP_BAN; /* supports propagated bans */
|
extern unsigned int CAP_BAN; /* supports propagated bans */
|
||||||
extern unsigned int CAP_MLOCK; /* supports MLOCK messages */
|
extern unsigned int CAP_MLOCK; /* supports MLOCK messages */
|
||||||
|
extern unsigned int CAP_EBMASK; /* supports sending BMASK set by/at metadata */
|
||||||
|
|
||||||
/* XXX: added for backwards compatibility. --nenolod */
|
/* XXX: added for backwards compatibility. --nenolod */
|
||||||
#define CAP_MASK (capability_index_mask(serv_capindex) & ~(CAP_TS6 | CAP_CAP))
|
#define CAP_MASK (capability_index_mask(serv_capindex) & ~(CAP_TS6 | CAP_CAP))
|
||||||
|
|
|
@ -237,10 +237,10 @@ allow_mode_change(struct Client *source_p, struct Channel *chptr, int alevel,
|
||||||
/* add_id()
|
/* add_id()
|
||||||
*
|
*
|
||||||
* inputs - client, channel, id to add, type, forward
|
* inputs - client, channel, id to add, type, forward
|
||||||
* outputs - false on failure, true on success
|
* outputs - NULL on failure, allocated Ban on success
|
||||||
* side effects - given id is added to the appropriate list
|
* side effects - given id is added to the appropriate list
|
||||||
*/
|
*/
|
||||||
bool
|
struct Ban *
|
||||||
add_id(struct Client *source_p, struct Channel *chptr, const char *banid, const char *forward,
|
add_id(struct Client *source_p, struct Channel *chptr, const char *banid, const char *forward,
|
||||||
rb_dlink_list * list, long mode_type)
|
rb_dlink_list * list, long mode_type)
|
||||||
{
|
{
|
||||||
|
@ -256,7 +256,7 @@ add_id(struct Client *source_p, struct Channel *chptr, const char *banid, const
|
||||||
{
|
{
|
||||||
sendto_one(source_p, form_str(ERR_BANLISTFULL),
|
sendto_one(source_p, form_str(ERR_BANLISTFULL),
|
||||||
me.name, source_p->name, chptr->chname, realban);
|
me.name, source_p->name, chptr->chname, realban);
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ add_id(struct Client *source_p, struct Channel *chptr, const char *banid, const
|
||||||
{
|
{
|
||||||
actualBan = ptr->data;
|
actualBan = ptr->data;
|
||||||
if(!irccmp(actualBan->banstr, realban))
|
if(!irccmp(actualBan->banstr, realban))
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(IsPerson(source_p))
|
if(IsPerson(source_p))
|
||||||
|
@ -282,7 +282,7 @@ add_id(struct Client *source_p, struct Channel *chptr, const char *banid, const
|
||||||
if(mode_type == CHFL_BAN || mode_type == CHFL_QUIET || mode_type == CHFL_EXCEPTION)
|
if(mode_type == CHFL_BAN || mode_type == CHFL_QUIET || mode_type == CHFL_EXCEPTION)
|
||||||
chptr->bants = rb_current_time();
|
chptr->bants = rb_current_time();
|
||||||
|
|
||||||
return true;
|
return actualBan;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* del_id()
|
/* del_id()
|
||||||
|
|
|
@ -86,6 +86,7 @@ unsigned int CAP_EUID;
|
||||||
unsigned int CAP_EOPMOD;
|
unsigned int CAP_EOPMOD;
|
||||||
unsigned int CAP_BAN;
|
unsigned int CAP_BAN;
|
||||||
unsigned int CAP_MLOCK;
|
unsigned int CAP_MLOCK;
|
||||||
|
unsigned int CAP_EBMASK;
|
||||||
|
|
||||||
unsigned int CLICAP_MULTI_PREFIX;
|
unsigned int CLICAP_MULTI_PREFIX;
|
||||||
unsigned int CLICAP_ACCOUNT_NOTIFY;
|
unsigned int CLICAP_ACCOUNT_NOTIFY;
|
||||||
|
@ -126,6 +127,7 @@ init_builtin_capabs(void)
|
||||||
CAP_EOPMOD = capability_put(serv_capindex, "EOPMOD", NULL);
|
CAP_EOPMOD = capability_put(serv_capindex, "EOPMOD", NULL);
|
||||||
CAP_BAN = capability_put(serv_capindex, "BAN", NULL);
|
CAP_BAN = capability_put(serv_capindex, "BAN", NULL);
|
||||||
CAP_MLOCK = capability_put(serv_capindex, "MLOCK", NULL);
|
CAP_MLOCK = capability_put(serv_capindex, "MLOCK", NULL);
|
||||||
|
CAP_EBMASK = capability_put(serv_capindex, "EBMASK", NULL);
|
||||||
|
|
||||||
capability_require(serv_capindex, "QS");
|
capability_require(serv_capindex, "QS");
|
||||||
capability_require(serv_capindex, "EX");
|
capability_require(serv_capindex, "EX");
|
||||||
|
@ -511,8 +513,9 @@ burst_modes_TS6(struct Client *client_p, struct Channel *chptr,
|
||||||
rb_dlink_node *ptr;
|
rb_dlink_node *ptr;
|
||||||
struct Ban *banptr;
|
struct Ban *banptr;
|
||||||
|
|
||||||
send_multiline_init(client_p, " ", ":%s BMASK %ld %s %c :",
|
send_multiline_init(client_p, " ", ":%s %s %ld %s %c :",
|
||||||
me.id,
|
me.id,
|
||||||
|
IsCapable(client_p, CAP_EBMASK) ? "EBMASK" : "BMASK",
|
||||||
(long)chptr->channelts,
|
(long)chptr->channelts,
|
||||||
chptr->chname,
|
chptr->chname,
|
||||||
flag);
|
flag);
|
||||||
|
@ -522,11 +525,18 @@ burst_modes_TS6(struct Client *client_p, struct Channel *chptr,
|
||||||
banptr = ptr->data;
|
banptr = ptr->data;
|
||||||
|
|
||||||
if (banptr->forward)
|
if (banptr->forward)
|
||||||
send_multiline_item(client_p, "%s$%s",
|
sprintf(buf, "%s$%s", banptr->banstr, banptr->forward);
|
||||||
banptr->banstr,
|
|
||||||
banptr->forward);
|
|
||||||
else
|
else
|
||||||
send_multiline_item(client_p, "%s", banptr->banstr);
|
strcpy(buf, banptr->banstr);
|
||||||
|
|
||||||
|
if IsCapable(client_p, CAP_EBMASK)
|
||||||
|
send_multiline_item(client_p, "%s %ld %s",
|
||||||
|
buf,
|
||||||
|
(long)banptr->when,
|
||||||
|
banptr->who);
|
||||||
|
else
|
||||||
|
send_multiline_item(client_p, "%s", buf);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
send_multiline_fini(client_p, NULL);
|
send_multiline_fini(client_p, NULL);
|
||||||
|
|
|
@ -48,6 +48,7 @@ static void ms_mode(struct MsgBuf *, struct Client *, struct Client *, int, cons
|
||||||
static void ms_tmode(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
|
static void ms_tmode(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
|
||||||
static void ms_mlock(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
|
static void ms_mlock(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
|
||||||
static void ms_bmask(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
|
static void ms_bmask(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
|
||||||
|
static void ms_ebmask(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
|
||||||
|
|
||||||
struct Message mode_msgtab = {
|
struct Message mode_msgtab = {
|
||||||
"MODE", 0, 0, 0, 0,
|
"MODE", 0, 0, 0, 0,
|
||||||
|
@ -65,8 +66,12 @@ struct Message bmask_msgtab = {
|
||||||
"BMASK", 0, 0, 0, 0,
|
"BMASK", 0, 0, 0, 0,
|
||||||
{mg_ignore, mg_ignore, mg_ignore, {ms_bmask, 5}, mg_ignore, mg_ignore}
|
{mg_ignore, mg_ignore, mg_ignore, {ms_bmask, 5}, mg_ignore, mg_ignore}
|
||||||
};
|
};
|
||||||
|
struct Message ebmask_msgtab = {
|
||||||
|
"EBMASK", 0, 0, 0, 0,
|
||||||
|
{mg_ignore, mg_ignore, mg_ignore, {ms_ebmask, 5}, mg_ignore, mg_ignore}
|
||||||
|
};
|
||||||
|
|
||||||
mapi_clist_av1 mode_clist[] = { &mode_msgtab, &tmode_msgtab, &mlock_msgtab, &bmask_msgtab, NULL };
|
mapi_clist_av1 mode_clist[] = { &mode_msgtab, &tmode_msgtab, &mlock_msgtab, &bmask_msgtab, &ebmask_msgtab, NULL };
|
||||||
|
|
||||||
DECLARE_MODULE_AV2(mode, NULL, NULL, mode_clist, NULL, NULL, NULL, NULL, mode_desc);
|
DECLARE_MODULE_AV2(mode, NULL, NULL, mode_clist, NULL, NULL, NULL, NULL, mode_desc);
|
||||||
|
|
||||||
|
@ -256,16 +261,19 @@ possibly_remove_lower_forward(struct Client *fakesource_p, int mems,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ms_bmask(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
|
do_bmask(bool extended, struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
|
||||||
{
|
{
|
||||||
static char modebuf[BUFSIZE];
|
static char output[BUFSIZE];
|
||||||
static char parabuf[BUFSIZE];
|
static char parabuf[BUFSIZE];
|
||||||
|
static char degrade[BUFSIZE];
|
||||||
|
static char squitreason[120];
|
||||||
struct Channel *chptr;
|
struct Channel *chptr;
|
||||||
|
struct Ban *banptr;
|
||||||
rb_dlink_list *banlist;
|
rb_dlink_list *banlist;
|
||||||
char *s, *forward;
|
char *s, *mask, *forward, *who;
|
||||||
char *t;
|
char *output_ptr;
|
||||||
char *mbuf;
|
char *param_ptr;
|
||||||
char *pbuf;
|
char *degrade_ptr;
|
||||||
long mode_type;
|
long mode_type;
|
||||||
int mlen;
|
int mlen;
|
||||||
int plen = 0;
|
int plen = 0;
|
||||||
|
@ -274,6 +282,7 @@ ms_bmask(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
int modecount = 0;
|
int modecount = 0;
|
||||||
int needcap = NOCAPS;
|
int needcap = NOCAPS;
|
||||||
int mems;
|
int mems;
|
||||||
|
time_t when = (long)rb_current_time();
|
||||||
struct Client *fakesource_p;
|
struct Client *fakesource_p;
|
||||||
|
|
||||||
if(!IsChanPrefix(parv[2][0]) || !check_channel_name(parv[2]))
|
if(!IsChanPrefix(parv[2][0]) || !check_channel_name(parv[2]))
|
||||||
|
@ -327,29 +336,29 @@ ms_bmask(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
fakesource_p = &me;
|
fakesource_p = &me;
|
||||||
else
|
else
|
||||||
fakesource_p = source_p;
|
fakesource_p = source_p;
|
||||||
mlen = sprintf(modebuf, ":%s MODE %s +", fakesource_p->name, chptr->chname);
|
who = fakesource_p->name;
|
||||||
mbuf = modebuf + mlen;
|
|
||||||
pbuf = parabuf;
|
mlen = sprintf(output, ":%s MODE %s +", fakesource_p->name, chptr->chname);
|
||||||
|
output_ptr = output + mlen;
|
||||||
|
param_ptr = parabuf;
|
||||||
|
degrade_ptr = degrade;
|
||||||
|
|
||||||
while(*s == ' ')
|
while(*s == ' ')
|
||||||
s++;
|
s++;
|
||||||
|
|
||||||
/* next char isnt a space, point t to the next one */
|
s = strtok(s, " ");
|
||||||
if((t = strchr(s, ' ')) != NULL)
|
|
||||||
{
|
|
||||||
*t++ = '\0';
|
|
||||||
|
|
||||||
/* double spaces will break the parser */
|
|
||||||
while(*t == ' ')
|
|
||||||
t++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* couldve skipped spaces and got nothing.. */
|
|
||||||
while(!EmptyString(s))
|
while(!EmptyString(s))
|
||||||
{
|
{
|
||||||
/* ban with a leading ':' -- this will break the protocol */
|
|
||||||
if(*s == ':')
|
if(*s == ':')
|
||||||
goto nextban;
|
{
|
||||||
|
/* ban with a leading ':' -- this will break the protocol */
|
||||||
|
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
|
||||||
|
"Link %s dropped, invalid BMASK mask (%s)", source_p->name, s);
|
||||||
|
snprintf(squitreason, sizeof squitreason, "Invalid BMASK mask (%s)", s);
|
||||||
|
exit_client(client_p, client_p, client_p, squitreason);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tlen = strlen(s);
|
tlen = strlen(s);
|
||||||
|
|
||||||
|
@ -368,53 +377,83 @@ ms_bmask(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
parv[3][0], s, forward);
|
parv[3][0], s, forward);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(add_id(fakesource_p, chptr, s, forward, banlist, mode_type))
|
mask = s;
|
||||||
|
if (extended) {
|
||||||
|
when = atol(strtok(NULL, " "));
|
||||||
|
who = strtok(NULL, " ");
|
||||||
|
if (who == NULL)
|
||||||
{
|
{
|
||||||
|
/* EBMASK params don't divide by 3, so we have an incomplete chunk */
|
||||||
|
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
|
||||||
|
"Link %s dropped, invalid EBMASK chunk", source_p->name);
|
||||||
|
snprintf(squitreason, sizeof squitreason, "Invalid EBMASK chunk");
|
||||||
|
exit_client(client_p, client_p, client_p, squitreason);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
arglen = sprintf(degrade_ptr, "%s ", mask);
|
||||||
|
degrade_ptr += arglen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((banptr = add_id(fakesource_p, chptr, mask, forward, banlist, mode_type)) != NULL)
|
||||||
|
{
|
||||||
|
banptr->when = when;
|
||||||
|
rb_free(banptr->who);
|
||||||
|
banptr->who = rb_strdup(who);
|
||||||
|
|
||||||
/* this new one wont fit.. */
|
/* this new one wont fit.. */
|
||||||
if(mlen + MAXMODEPARAMS + plen + tlen > BUFSIZE - 5 ||
|
if(mlen + MAXMODEPARAMS + plen + tlen > BUFSIZE - 5 ||
|
||||||
modecount >= MAXMODEPARAMS)
|
modecount >= MAXMODEPARAMS)
|
||||||
{
|
{
|
||||||
*mbuf = '\0';
|
*output_ptr = '\0';
|
||||||
*(pbuf - 1) = '\0';
|
*(param_ptr - 1) = '\0';
|
||||||
sendto_channel_local(fakesource_p, mems, chptr, "%s %s", modebuf, parabuf);
|
sendto_channel_local(fakesource_p, mems, chptr, "%s %s", output, parabuf);
|
||||||
|
|
||||||
mbuf = modebuf + mlen;
|
output_ptr = output + mlen;
|
||||||
pbuf = parabuf;
|
param_ptr = parabuf;
|
||||||
plen = modecount = 0;
|
plen = modecount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (forward != NULL)
|
if (forward != NULL)
|
||||||
forward[-1] = '$';
|
forward[-1] = '$';
|
||||||
|
|
||||||
*mbuf++ = parv[3][0];
|
*output_ptr++ = parv[3][0];
|
||||||
arglen = sprintf(pbuf, "%s ", s);
|
arglen = sprintf(param_ptr, "%s ", mask);
|
||||||
pbuf += arglen;
|
param_ptr += arglen;
|
||||||
plen += arglen;
|
plen += arglen;
|
||||||
modecount++;
|
modecount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextban:
|
s = strtok(NULL, " ");
|
||||||
s = t;
|
|
||||||
|
|
||||||
if(s != NULL)
|
|
||||||
{
|
|
||||||
if((t = strchr(s, ' ')) != NULL)
|
|
||||||
{
|
|
||||||
*t++ = '\0';
|
|
||||||
|
|
||||||
while(*t == ' ')
|
|
||||||
t++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(modecount)
|
if(modecount)
|
||||||
{
|
{
|
||||||
*mbuf = '\0';
|
*output_ptr = '\0';
|
||||||
*(pbuf - 1) = '\0';
|
*(param_ptr - 1) = '\0';
|
||||||
sendto_channel_local(fakesource_p, mems, chptr, "%s %s", modebuf, parabuf);
|
sendto_channel_local(fakesource_p, mems, chptr, "%s %s", output, parabuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (extended) {
|
||||||
|
*(degrade_ptr - 1) = '\0';
|
||||||
|
sendto_server(client_p, chptr, CAP_EBMASK | CAP_TS6 | needcap, NOCAPS, ":%s EBMASK %ld %s %s :%s",
|
||||||
|
source_p->id, (long) chptr->channelts, chptr->chname, parv[3], parv[4]);
|
||||||
|
sendto_server(client_p, chptr, CAP_TS6 | needcap, CAP_EBMASK, ":%s BMASK %ld %s %s :%s",
|
||||||
|
source_p->id, (long) chptr->channelts, chptr->chname, parv[3], degrade);
|
||||||
|
}
|
||||||
|
else
|
||||||
sendto_server(client_p, chptr, CAP_TS6 | needcap, NOCAPS, ":%s BMASK %ld %s %s :%s",
|
sendto_server(client_p, chptr, CAP_TS6 | needcap, NOCAPS, ":%s BMASK %ld %s %s :%s",
|
||||||
source_p->id, (long) chptr->channelts, chptr->chname, parv[3], parv[4]);
|
source_p->id, (long) chptr->channelts, chptr->chname, parv[3], parv[4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ms_bmask(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
|
||||||
|
{
|
||||||
|
do_bmask(false, msgbuf_p, client_p, source_p, parc, parv);
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
ms_ebmask(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
|
||||||
|
{
|
||||||
|
do_bmask(true, msgbuf_p, client_p, source_p, parc, parv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue