From 0b8910e40bdf7deb610382455bed5305ac15c086 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Fri, 26 Jun 2020 11:41:05 -0600 Subject: [PATCH 01/13] invite: remove hardcoded UMODE_REGONLYMSG code --- modules/m_invite.c | 50 ++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/modules/m_invite.c b/modules/m_invite.c index 08bda62f..77ff593a 100644 --- a/modules/m_invite.c +++ b/modules/m_invite.c @@ -158,7 +158,7 @@ m_invite(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source { if (hdata.error) sendto_one_numeric(source_p, hdata.approved, "%s", hdata.error); - else + else if (hdata.approved == ERR_CHANOPRIVSNEEDED) sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), me.name, source_p->name, parv[2]); return; @@ -200,40 +200,28 @@ m_invite(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source if(MyConnect(target_p)) { - if(!IsOper(source_p) && (IsSetCallerId(target_p) || - (IsSetRegOnlyMsg(target_p) && !source_p->user->suser[0])) && - !accept_message(source_p, target_p)) + if(!IsOper(source_p) && (IsSetCallerId(target_p)) && !accept_message(source_p, target_p)) { - if (IsSetRegOnlyMsg(target_p) && !source_p->user->suser[0]) + sendto_one_numeric(source_p, ERR_TARGUMODEG, + form_str(ERR_TARGUMODEG), + target_p->name); + + if((target_p->localClient->last_caller_id_time + + ConfigFileEntry.caller_id_wait) < rb_current_time()) { - sendto_one_numeric(source_p, ERR_NONONREG, - form_str(ERR_NONONREG), - target_p->name); - return; + sendto_one_numeric(source_p, RPL_TARGNOTIFY, + form_str(RPL_TARGNOTIFY), + target_p->name); + + add_reply_target(target_p, source_p); + sendto_one(target_p, form_str(RPL_UMODEGMSG), + me.name, target_p->name, source_p->name, + source_p->username, source_p->host); + + target_p->localClient->last_caller_id_time = rb_current_time(); } - else - { - sendto_one_numeric(source_p, ERR_TARGUMODEG, - form_str(ERR_TARGUMODEG), - target_p->name); - if((target_p->localClient->last_caller_id_time + - ConfigFileEntry.caller_id_wait) < rb_current_time()) - { - sendto_one_numeric(source_p, RPL_TARGNOTIFY, - form_str(RPL_TARGNOTIFY), - target_p->name); - - add_reply_target(target_p, source_p); - sendto_one(target_p, form_str(RPL_UMODEGMSG), - me.name, target_p->name, source_p->name, - source_p->username, source_p->host); - - target_p->localClient->last_caller_id_time = rb_current_time(); - } - - return; - } + return; } hdata.chptr = chptr; From ed3b56f9655658752e6904a7ae29689bc45e6329 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Fri, 26 Jun 2020 11:55:07 -0600 Subject: [PATCH 02/13] message: remove hardcoded +R logic --- modules/core/m_message.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/modules/core/m_message.c b/modules/core/m_message.c index 3c31554a..e329e7bf 100644 --- a/modules/core/m_message.c +++ b/modules/core/m_message.c @@ -725,8 +725,7 @@ msg_client(enum message_type msgtype, * as a way of griefing. --nenolod */ if(msgtype != MESSAGE_TYPE_NOTICE && - (IsSetCallerId(source_p) || - (IsSetRegOnlyMsg(source_p) && !target_p->user->suser[0])) && + IsSetCallerId(source_p) && !accept_message(target_p, source_p) && !IsOper(target_p)) { @@ -818,8 +817,7 @@ msg_client(enum message_type msgtype, } /* XXX Controversial? allow opers always to send through a +g */ - if(!IsServer(source_p) && (IsSetCallerId(target_p) || - (IsSetRegOnlyMsg(target_p) && !source_p->user->suser[0]))) + if(!IsServer(source_p) && IsSetCallerId(target_p)) { /* Here is the anti-flood bot/spambot code -db */ if(accept_message(source_p, target_p) || IsOper(source_p)) @@ -830,13 +828,6 @@ msg_client(enum message_type msgtype, source_p->username, source_p->host, cmdname[msgtype], target_p->name, text); } - else if (IsSetRegOnlyMsg(target_p) && !source_p->user->suser[0]) - { - if (msgtype != MESSAGE_TYPE_NOTICE) - sendto_one_numeric(source_p, ERR_NONONREG, - form_str(ERR_NONONREG), - target_p->name); - } else { /* check for accept, flag recipient incoming message */ From 968dee680f777012773c21a23dd698b693634104 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Fri, 26 Jun 2020 11:55:30 -0600 Subject: [PATCH 03/13] modularize usermode +R (registered users only) --- include/client.h | 2 - ircd/newconf.c | 1 - ircd/s_user.c | 2 +- modules/Makefile.am | 1 + modules/um_regonlymsg.c | 129 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 modules/um_regonlymsg.c diff --git a/include/client.h b/include/client.h index af8ccfa4..d3ff6a57 100644 --- a/include/client.h +++ b/include/client.h @@ -452,7 +452,6 @@ struct ListClient #define UMODE_SERVICE 0x0040 #define UMODE_DEAF 0x0080 #define UMODE_NOFORWARD 0x0100 /* don't forward */ -#define UMODE_REGONLYMSG 0x0200 /* only allow logged in users to msg */ /* user information flags, only settable by remote mode or local oper */ #define UMODE_OPER 0x1000 /* Operator */ @@ -543,7 +542,6 @@ struct ListClient #define IsService(x) ((x)->umodes & UMODE_SERVICE) #define IsDeaf(x) ((x)->umodes & UMODE_DEAF) #define IsNoForward(x) ((x)->umodes & UMODE_NOFORWARD) -#define IsSetRegOnlyMsg(x) ((x)->umodes & UMODE_REGONLYMSG) #define SetGotId(x) ((x)->flags |= FLAGS_GOTID) #define IsGotId(x) (((x)->flags & FLAGS_GOTID) != 0) diff --git a/ircd/newconf.c b/ircd/newconf.c index 7a540606..b69c3bfc 100644 --- a/ircd/newconf.c +++ b/ircd/newconf.c @@ -321,7 +321,6 @@ static struct mode_table umode_table[] = { {"invisible", UMODE_INVISIBLE }, {"locops", UMODE_LOCOPS }, {"noforward", UMODE_NOFORWARD }, - {"regonlymsg", UMODE_REGONLYMSG}, {"servnotice", UMODE_SERVNOTICE}, {"wallop", UMODE_WALLOP }, {"operwall", UMODE_OPERWALL }, diff --git a/ircd/s_user.c b/ircd/s_user.c index 06d3b6cb..5ac5f56e 100644 --- a/ircd/s_user.c +++ b/ircd/s_user.c @@ -81,7 +81,7 @@ int user_modes[256] = { 0, /* O */ 0, /* P */ UMODE_NOFORWARD, /* Q */ - UMODE_REGONLYMSG, /* R */ + 0, /* R */ UMODE_SERVICE, /* S */ 0, /* T */ 0, /* U */ diff --git a/modules/Makefile.am b/modules/Makefile.am index 8b06c829..7f532db7 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -15,6 +15,7 @@ auto_load_mod_LTLIBRARIES = \ cap_server_time.la \ chm_nocolour.la \ chm_noctcp.la \ + um_regonlymsg.la \ m_accept.la \ m_admin.la \ m_alias.la \ diff --git a/modules/um_regonlymsg.c b/modules/um_regonlymsg.c new file mode 100644 index 00000000..75467401 --- /dev/null +++ b/modules/um_regonlymsg.c @@ -0,0 +1,129 @@ +/* + * modules/um_regonlymsg.c + * Copyright (c) 2020 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdinc.h" +#include "modules.h" +#include "hook.h" +#include "client.h" +#include "ircd.h" +#include "send.h" +#include "hash.h" +#include "s_conf.h" +#include "s_user.h" +#include "s_serv.h" +#include "numeric.h" +#include "privilege.h" +#include "s_newconf.h" + +static int +um_regonlymsg_modinit(void) +{ + user_modes['R'] = find_umode_slot(); + construct_umodebuf(); + + return 0; +} + +static void +um_regonlymsg_moddeinit(void) +{ + user_modes['R'] = 0; + construct_umodebuf(); +} + +#define IsSetRegOnlyMsg(c) ((c->umodes & user_modes['R']) == user_modes['R']) + +static const char um_regonlymsg_desc[] = + "Provides usermode +R which restricts messages from unregistered users."; + +static bool +allow_message(struct Client *source_p, struct Client *target_p) +{ + if (!IsSetRegOnlyMsg(target_p)) + return false; + + if (IsServer(source_p)) + return false; + + /* XXX: controversial? allow opers to send through +R */ + if (IsOper(source_p)) + return false; + + if (accept_message(source_p, target_p)) + return false; + + if (source_p->user->suser[0]) + return false; + + return true; +} + +static void +h_can_invite(void *vdata) +{ + hook_data_channel_approval *data = vdata; + struct Client *source_p = data->client; + struct Client *target_p = data->target; + + if (allow_message(source_p, target_p)) + return; + + sendto_one_numeric(source_p, ERR_NONONREG, form_str(ERR_NONONREG), + target_p->name); + + data->approved = ERR_NONONREG; +} + +static void +h_hdl_privmsg_user(void *vdata) +{ + hook_data_privmsg_user *data = vdata; + struct Client *source_p = data->source_p; + struct Client *target_p = data->target_p; + + if (allow_message(source_p, target_p)) + return; + + if (data->msgtype == MESSAGE_TYPE_NOTICE) + return; + + sendto_one_numeric(source_p, ERR_NONONREG, form_str(ERR_NONONREG), + target_p->name); + + data->approved = ERR_NONONREG; +} + +static mapi_hfn_list_av1 um_regonlymsg_hfnlist[] = { + { "can_invite", h_can_invite }, + { "privmsg_user", h_hdl_privmsg_user }, + { NULL, NULL } +}; + +DECLARE_MODULE_AV2(um_regonlymsg, um_regonlymsg_modinit, um_regonlymsg_moddeinit, + NULL, NULL, um_regonlymsg_hfnlist, NULL, NULL, um_regonlymsg_desc); From dc5d1d012a7998ef8ff7f332298886b1abe2cdf7 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Fri, 26 Jun 2020 12:03:43 -0600 Subject: [PATCH 04/13] regonlymsg: fix allow_message() return values --- modules/um_regonlymsg.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/um_regonlymsg.c b/modules/um_regonlymsg.c index 75467401..27d4653f 100644 --- a/modules/um_regonlymsg.c +++ b/modules/um_regonlymsg.c @@ -66,22 +66,22 @@ static bool allow_message(struct Client *source_p, struct Client *target_p) { if (!IsSetRegOnlyMsg(target_p)) - return false; + return true; if (IsServer(source_p)) - return false; + return true; /* XXX: controversial? allow opers to send through +R */ if (IsOper(source_p)) - return false; + return true; if (accept_message(source_p, target_p)) - return false; + return true; if (source_p->user->suser[0]) - return false; + return true; - return true; + return false; } static void From 90e99760a099e19cf8ce5a5819e929e0ab6e84e2 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Fri, 26 Jun 2020 19:03:25 +0000 Subject: [PATCH 05/13] regonlymsg: do not clobber the work of other modules --- modules/um_regonlymsg.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/um_regonlymsg.c b/modules/um_regonlymsg.c index 27d4653f..79ca4cd6 100644 --- a/modules/um_regonlymsg.c +++ b/modules/um_regonlymsg.c @@ -91,6 +91,9 @@ h_can_invite(void *vdata) struct Client *source_p = data->client; struct Client *target_p = data->target; + if (data->approved) + return; + if (allow_message(source_p, target_p)) return; @@ -107,6 +110,9 @@ h_hdl_privmsg_user(void *vdata) struct Client *source_p = data->source_p; struct Client *target_p = data->target_p; + if (data->approved) + return; + if (allow_message(source_p, target_p)) return; From 4436a7ca73eec154f2cc12a2340790220c256efe Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Fri, 26 Jun 2020 19:46:57 +0000 Subject: [PATCH 06/13] regonlymsg: allow messages through if target is not a local client --- modules/um_regonlymsg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/um_regonlymsg.c b/modules/um_regonlymsg.c index 79ca4cd6..00a7b2ad 100644 --- a/modules/um_regonlymsg.c +++ b/modules/um_regonlymsg.c @@ -65,6 +65,9 @@ static const char um_regonlymsg_desc[] = static bool allow_message(struct Client *source_p, struct Client *target_p) { + if (!MyClient(target_p)) + return true; + if (!IsSetRegOnlyMsg(target_p)) return true; From 4371dcbd55928135796c5d369cb06583b777565a Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Fri, 26 Jun 2020 19:55:12 +0000 Subject: [PATCH 07/13] invite: rework the way can_invite hook is called --- modules/m_invite.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/modules/m_invite.c b/modules/m_invite.c index 77ff593a..dcd965e5 100644 --- a/modules/m_invite.c +++ b/modules/m_invite.c @@ -145,24 +145,27 @@ m_invite(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source return; } - if (MyClient(source_p)) - { - hdata.chptr = chptr; - hdata.msptr = msptr; - hdata.client = source_p; - hdata.target = target_p; - hdata.approved = !(is_chanop(msptr) || (chptr->mode.mode & MODE_FREEINVITE)); + hdata.chptr = chptr; + hdata.msptr = msptr; + hdata.client = source_p; + hdata.target = target_p; + hdata.approved = !(is_chanop(msptr) || (chptr->mode.mode & MODE_FREEINVITE)); - call_hook(can_invite_hook, &hdata); - if (hdata.approved) + call_hook(can_invite_hook, &hdata); + if (hdata.approved) + { + if (MyClient(target_p)) { if (hdata.error) sendto_one_numeric(source_p, hdata.approved, "%s", hdata.error); else if (hdata.approved == ERR_CHANOPRIVSNEEDED) sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), - me.name, source_p->name, parv[2]); - return; + me.name, source_p->name, parv[2]); + + add_reply_target(target_p, source_p); } + + return; } /* store invites when they could affect the ability to join From ddb063e2f9f956157cdf1f667209f742f328d68d Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Fri, 26 Jun 2020 13:58:00 -0600 Subject: [PATCH 08/13] invite: remove redundant parenthesis --- modules/m_invite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/m_invite.c b/modules/m_invite.c index dcd965e5..e097930c 100644 --- a/modules/m_invite.c +++ b/modules/m_invite.c @@ -203,7 +203,7 @@ m_invite(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source if(MyConnect(target_p)) { - if(!IsOper(source_p) && (IsSetCallerId(target_p)) && !accept_message(source_p, target_p)) + if(!IsOper(source_p) && IsSetCallerId(target_p) && !accept_message(source_p, target_p)) { sendto_one_numeric(source_p, ERR_TARGUMODEG, form_str(ERR_TARGUMODEG), From e3c27d7dbde007efbb19d1dc34f0581fd4ca1778 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Fri, 26 Jun 2020 14:20:52 -0600 Subject: [PATCH 09/13] Revert "invite: rework the way can_invite hook is called" This reverts commit ed06fed70a67b0cdd4e53aad575fca7b9d046061. --- modules/m_invite.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/modules/m_invite.c b/modules/m_invite.c index e097930c..71bd0ab6 100644 --- a/modules/m_invite.c +++ b/modules/m_invite.c @@ -145,27 +145,28 @@ m_invite(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source return; } - hdata.chptr = chptr; - hdata.msptr = msptr; - hdata.client = source_p; - hdata.target = target_p; - hdata.approved = !(is_chanop(msptr) || (chptr->mode.mode & MODE_FREEINVITE)); - - call_hook(can_invite_hook, &hdata); - if (hdata.approved) + if (MyClient(source_p)) { - if (MyClient(target_p)) + hdata.chptr = chptr; + hdata.msptr = msptr; + hdata.client = source_p; + hdata.target = target_p; + hdata.approved = !(is_chanop(msptr) || (chptr->mode.mode & MODE_FREEINVITE)); + + call_hook(can_invite_hook, &hdata); + if (hdata.approved) { if (hdata.error) sendto_one_numeric(source_p, hdata.approved, "%s", hdata.error); else if (hdata.approved == ERR_CHANOPRIVSNEEDED) sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), - me.name, source_p->name, parv[2]); + me.name, source_p->name, parv[2]); - add_reply_target(target_p, source_p); + if (MyClient(target_p)) + add_reply_target(target_p, source_p); + + return; } - - return; } /* store invites when they could affect the ability to join From 27590ae0b44895f98ad1bae39e0c9947185a619d Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Fri, 26 Jun 2020 14:21:29 -0600 Subject: [PATCH 10/13] invite: revert the ERR_CHANOPRIVSNEEDED change too --- modules/m_invite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/m_invite.c b/modules/m_invite.c index 71bd0ab6..26c5024d 100644 --- a/modules/m_invite.c +++ b/modules/m_invite.c @@ -158,7 +158,7 @@ m_invite(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source { if (hdata.error) sendto_one_numeric(source_p, hdata.approved, "%s", hdata.error); - else if (hdata.approved == ERR_CHANOPRIVSNEEDED) + else sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), me.name, source_p->name, parv[2]); From daaf127d84224c72e8f7915be34c069dba10e886 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Fri, 26 Jun 2020 14:22:31 -0600 Subject: [PATCH 11/13] regonlymsg: use invite instead of can_invite hook --- modules/um_regonlymsg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/um_regonlymsg.c b/modules/um_regonlymsg.c index 00a7b2ad..6ecea709 100644 --- a/modules/um_regonlymsg.c +++ b/modules/um_regonlymsg.c @@ -88,7 +88,7 @@ allow_message(struct Client *source_p, struct Client *target_p) } static void -h_can_invite(void *vdata) +h_hdl_invite(void *vdata) { hook_data_channel_approval *data = vdata; struct Client *source_p = data->client; @@ -129,7 +129,7 @@ h_hdl_privmsg_user(void *vdata) } static mapi_hfn_list_av1 um_regonlymsg_hfnlist[] = { - { "can_invite", h_can_invite }, + { "invite", h_hdl_invite }, { "privmsg_user", h_hdl_privmsg_user }, { NULL, NULL } }; From 2bbfce681f040621814a400142112a68e39d0b12 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Fri, 26 Jun 2020 14:32:46 -0600 Subject: [PATCH 12/13] regonlymsg: catch find_umode_slot() failure --- modules/um_regonlymsg.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/um_regonlymsg.c b/modules/um_regonlymsg.c index 6ecea709..224a4690 100644 --- a/modules/um_regonlymsg.c +++ b/modules/um_regonlymsg.c @@ -40,6 +40,7 @@ #include "numeric.h" #include "privilege.h" #include "s_newconf.h" +#include "logger.h" static int um_regonlymsg_modinit(void) @@ -47,6 +48,12 @@ um_regonlymsg_modinit(void) user_modes['R'] = find_umode_slot(); construct_umodebuf(); + if (!user_modes['R']) + { + ierror("um_regonlymsg: unable to allocate usermode slot for +R, unloading module"); + return -1; + } + return 0; } From 402b21d47a53cf7c8cb5fe37193a71cde03d374c Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Fri, 26 Jun 2020 15:34:22 -0600 Subject: [PATCH 13/13] regonlymsg: use hdata.error where available --- modules/um_regonlymsg.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/um_regonlymsg.c b/modules/um_regonlymsg.c index 224a4690..3b31006a 100644 --- a/modules/um_regonlymsg.c +++ b/modules/um_regonlymsg.c @@ -100,6 +100,7 @@ h_hdl_invite(void *vdata) hook_data_channel_approval *data = vdata; struct Client *source_p = data->client; struct Client *target_p = data->target; + static char errorbuf[BUFSIZE]; if (data->approved) return; @@ -107,10 +108,11 @@ h_hdl_invite(void *vdata) if (allow_message(source_p, target_p)) return; - sendto_one_numeric(source_p, ERR_NONONREG, form_str(ERR_NONONREG), - target_p->name); + snprintf(errorbuf, sizeof errorbuf, form_str(ERR_NONONREG), + target_p->name); data->approved = ERR_NONONREG; + data->error = errorbuf; } static void