From 53c987b331d49ecc40a0076e6f517121c34466a9 Mon Sep 17 00:00:00 2001 From: Ryan Schmidt Date: Mon, 28 Mar 2022 15:57:57 -0700 Subject: [PATCH] Add ability to mark webirc users and forbid marked users Marked connections (via set_mark in the webirc auth block) will be checked against the forbid_mark flag in the final auth block after resolving the user's spoofed IP. This allows for additional levels of security from webirc operators so that they are unable to spoof their way into privileged auth blocks -- an auth block with forbid_mark will reject any connections from marked users. The mark is not automatic because some webirc servers may be fully trusted to allow privileged users to connect (such as a webchat hosted by the network itself). --- doc/reference.conf | 3 +++ extensions/m_webirc.c | 11 +++++++++++ include/s_conf.h | 2 ++ ircd/newconf.c | 2 ++ ircd/s_conf.c | 8 ++++++++ 5 files changed, 26 insertions(+) diff --git a/doc/reference.conf b/doc/reference.conf index 368c5a70c..8e8fda1f5 100644 --- a/doc/reference.conf +++ b/doc/reference.conf @@ -394,6 +394,9 @@ auth { * extend_chans | allow this user to join more channels than normal * kline_spoof_ip | if this block has a spoof host, klines match only * | the spoof and not the underlying IP + * set_mark | no-op by default; used by webirc to mark this user + * | before resolving their actual auth block + * forbid_mark | reject connections from marked users */ flags = kline_exempt, exceed_limit; diff --git a/extensions/m_webirc.c b/extensions/m_webirc.c index d0b648c3a..1c05cbf67 100644 --- a/extensions/m_webirc.c +++ b/extensions/m_webirc.c @@ -31,6 +31,8 @@ * Possible flags: * encrypted - password is encrypted (recommended) * kline_exempt - klines on the cgiirc ip are ignored + * set_mark - mark clients connecting via this block, interacts with + * forbid_mark when resolving the auth block for the spoofed ip * dlines are checked on the cgiirc ip (of course). * k/d/x lines, auth blocks, user limits, etc are checked using the * real host/ip. @@ -143,6 +145,15 @@ mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc source_p->username[0] = '\0'; ClearGotId(source_p); + /* set_mark and forbid_mark in an auth block both set CONF_FLAG_FORBIDMARK; + * the distinction is purely visual for the sake of human readability, + * hence checking IsConfForbidMark here. + */ + if (IsConfForbidMark(aconf)) + { + SetMark(source_p); + } + if (parc >= 6) { const char *s; diff --git a/include/s_conf.h b/include/s_conf.h index b8bb14049..5a33d47ab 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -110,6 +110,7 @@ struct ConfItem #define CONF_FLAGS_EXEMPTJUPE 0x00020000 /* exempt from resv generating warnings */ #define CONF_FLAGS_NEED_SASL 0x00040000 #define CONF_FLAGS_EXTEND_CHANS 0x00080000 +#define CONF_FLAGS_FORBIDMARK 0x00100000 #define CONF_FLAGS_ENCRYPTED 0x00200000 #define CONF_FLAGS_EXEMPTDNSBL 0x04000000 #define CONF_FLAGS_EXEMPTPROXY 0x08000000 @@ -132,6 +133,7 @@ struct ConfItem #define IsConfExemptResv(x) ((x)->flags & CONF_FLAGS_EXEMPTRESV) #define IsConfDoSpoofIp(x) ((x)->flags & CONF_FLAGS_SPOOF_IP) #define IsConfSpoofNotice(x) ((x)->flags & CONF_FLAGS_SPOOF_NOTICE) +#define IsConfForbidMark(x) ((x)->flags & CONF_FLAGS_FORBIDMARK) #define IsConfEncrypted(x) ((x)->flags & CONF_FLAGS_ENCRYPTED) #define IsNeedSasl(x) ((x)->flags & CONF_FLAGS_NEED_SASL) #define IsConfExemptDNSBL(x) ((x)->flags & CONF_FLAGS_EXEMPTDNSBL) diff --git a/ircd/newconf.c b/ircd/newconf.c index 101942f97..4a443c106 100644 --- a/ircd/newconf.c +++ b/ircd/newconf.c @@ -351,6 +351,8 @@ static struct mode_table auth_table[] = { {"extend_chans", CONF_FLAGS_EXTEND_CHANS }, {"allow_sctp", CONF_FLAGS_ALLOW_SCTP }, {"kline_spoof_ip", CONF_FLAGS_KLINE_SPOOF }, + {"set_mark", CONF_FLAGS_FORBIDMARK }, + {"forbid_mark", CONF_FLAGS_FORBIDMARK }, {NULL, 0} }; diff --git a/ircd/s_conf.c b/ircd/s_conf.c index 406e7103a..c018fef68 100644 --- a/ircd/s_conf.c +++ b/ircd/s_conf.c @@ -325,6 +325,14 @@ verify_access(struct Client *client_p, const char *username) return (NOT_AUTHORISED); } + if(IsMarked(client_p)) + { + if(IsConfForbidMark(aconf)) + return NOT_AUTHORISED; + + ClearMark(client_p); + } + /* Thanks for spoof idea amm */ if(IsConfDoSpoofIp(aconf)) {