]> jfr.im git - irc/quakenet/snircd-patchqueue.git/blame - centralizemodecccheck.patch
centralizemodecccheck: updated description in file, added assert checks, improved...
[irc/quakenet/snircd-patchqueue.git] / centralizemodecccheck.patch
CommitLineData
97b63806 1centralize mode checks for +c (no control codes) and +C (no CTCPs)
2
3add client_can_send_controlcode_or_ctcp_to_channel() function in channel.c
4and use that (2x ircd_relay.c, m_wallchops.c, m_wallvoices.c), instead of duplicating code 4 times
a42ed697 5function uses a table to check for control codes, which is faster than what was used before
97b63806 6also corrects that an error is returned in WALLVOICES and WALLCHOPS in case +c or +C blocks the message, which is also done for other modes there
a42ed697 7also corrects that CTCP ACTION is only allowed for PRIVMSG, and not for NOTICE WALLCHOPS and WALLVOICES
97b63806 8
d2d7c538 9diff -r e80591f05c47 include/channel.h
10--- a/include/channel.h Sat Mar 20 17:57:13 2010 +0100
a42ed697 11+++ b/include/channel.h Sun Mar 21 15:49:28 2010 +0100
97b63806 12@@ -398,6 +398,7 @@
13 extern struct Membership* find_channel_member(struct Client* cptr, struct Channel* chptr);
14 extern int member_can_send_to_channel(struct Membership* member, int reveal);
15 extern int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int reveal);
16+extern int client_can_send_controlcode_or_ctcp_to_channel(struct Client *cptr, struct Channel *chptr, const char *text, int action);
17
18 extern void remove_user_from_channel(struct Client *sptr, struct Channel *chptr);
19 extern void remove_user_from_all_channels(struct Client* cptr);
d2d7c538 20diff -r e80591f05c47 ircd/channel.c
21--- a/ircd/channel.c Sat Mar 20 17:57:13 2010 +0100
a42ed697 22+++ b/ircd/channel.c Sun Mar 21 15:49:28 2010 +0100
23@@ -778,6 +778,63 @@
97b63806 24 return member_can_send_to_channel(member, reveal);
25 }
26
a42ed697 27+/** Table with control chars that should be blocked by chanmode +c
28+ *
29+ * codes: bold 2, colour 3, reverse 22, ansi escape 27, underline 31
30+ *
31+ */
32+static int control_codes[256] = {
33+ 0, 0, 1, 1, 0, 0, 0, 0,
34+ 0, 0, 0, 0, 0, 0, 0, 0,
35+ 0, 0, 0, 0, 0, 0, 1, 0,
36+ 0, 0, 0, 1, 0, 0, 0, 1,
37+};
38+
97b63806 39+/** Check if a client can send control codes or CTCP to a channel
40+ *
41+ * @param cptr The client to check
42+ * @param chptr The channel to check
43+ * @param text The text to check for control codes and/or CTCP chars
44+ * @param action When 1 allow CTCP ACTION (for PRIVMSG),
45+ * else dont allow (for NOTICE, WALLCHOPS, and WALLVOICES)
46+ *
47+ * @returns true if the client is allowed to speak on the channel, false
48+ * otherwise
49+ *
50+ */
51+int client_can_send_controlcode_or_ctcp_to_channel(struct Client *cptr, struct Channel *chptr, const char *text, int action)
52+{
53+ int control = 0, ctcp = 0;
a42ed697 54+ const unsigned char *chr;
55+
56+ assert(0 != cptr);
57+ assert(0 != chptr);
97b63806 58+
59+ /* dont check this for remote users or servers - fail safe */
60+ if (!MyUser(cptr) || IsServer(cptr))
61+ return 1;
62+
63+ /* mode +c set */
64+ if (chptr->mode.mode & MODE_NOCOLOUR)
65+ control = 1;
66+
67+ /* mode +C set - do allow CTCP ACTION though but only when action is 1 */
68+ if ((chptr->mode.mode & MODE_NOCTCP) && (!action || ircd_strncmp(text,"\001ACTION ",8)))
69+ ctcp = 1;
70+
71+ /* nothing to check */
72+ if (!control && !ctcp)
73+ return 1;
74+
75+ /* search for control codes and/or CTCP chars */
76+ for (chr=text;*chr;chr++) {
a42ed697 77+ if ((ctcp && *chr==1) || (control && control_codes[*chr]))
97b63806 78+ return 0;
79+ }
80+
81+ return 1;
82+}
83+
84 /** Returns the name of a channel that prevents the user from changing nick.
85 * if a member and not (opped or voiced) and (banned or moderated), return
86 * the name of the first channel banned on.
d2d7c538 87diff -r e80591f05c47 ircd/ircd_relay.c
88--- a/ircd/ircd_relay.c Sat Mar 20 17:57:13 2010 +0100
a42ed697 89+++ b/ircd/ircd_relay.c Sun Mar 21 15:49:28 2010 +0100
97b63806 90@@ -87,7 +87,6 @@
91 void relay_channel_message(struct Client* sptr, const char* name, const char* text, const int targetc)
92 {
93 struct Channel* chptr;
94- const char *ch;
95 assert(0 != sptr);
96 assert(0 != name);
97 assert(0 != text);
98@@ -111,19 +110,10 @@
99 }
100
101 /* +cC checks */
102- if (chptr->mode.mode & MODE_NOCOLOUR)
103- for (ch=text;*ch;ch++)
104- if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) {
105- send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
106- return;
107- }
108-
109- if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(text,"\001ACTION ",8))
110- for (ch=text;*ch;)
111- if (*ch++==1) {
112- send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
113- return;
114- }
115+ if (!client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, text, 1)) {
116+ send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
117+ return;
118+ }
119
120 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
121 check_target_limit(sptr, chptr, chptr->chname, 0))
122@@ -144,7 +134,6 @@
123 void relay_channel_notice(struct Client* sptr, const char* name, const char* text, const int targetc)
124 {
125 struct Channel* chptr;
126- const char *ch;
127 assert(0 != sptr);
128 assert(0 != name);
129 assert(0 != text);
130@@ -165,15 +154,8 @@
131 return;
132
133 /* +cC checks */
134- if (chptr->mode.mode & MODE_NOCOLOUR)
135- for (ch=text;*ch;ch++)
136- if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31)
137- return;
138-
139- if (chptr->mode.mode & MODE_NOCTCP)
140- for (ch=text;*ch;)
141- if (*ch++==1)
142- return;
143+ if (!client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, text, 0))
144+ return;
145
146 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
147 check_target_limit(sptr, chptr, chptr->chname, 0))
d2d7c538 148diff -r e80591f05c47 ircd/m_wallchops.c
149--- a/ircd/m_wallchops.c Sat Mar 20 17:57:13 2010 +0100
a42ed697 150+++ b/ircd/m_wallchops.c Sun Mar 21 15:49:28 2010 +0100
97b63806 151@@ -103,7 +103,6 @@
152 {
153 struct Channel *chptr;
154 struct Membership* member;
155- const char *ch;
156
157 assert(0 != cptr);
158 assert(cptr == sptr);
159@@ -117,20 +116,9 @@
160 return send_reply(sptr, ERR_NOTEXTTOSEND);
161
162 if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) {
163- if (client_can_send_to_channel(sptr, chptr, 0) && !(chptr->mode.mode & MODE_NONOTICE)) {
164-
165- /* +cC checks */
166- if (chptr->mode.mode & MODE_NOCOLOUR)
167- for (ch=parv[parc - 1];*ch;ch++)
168- if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) {
169- return 0;
170- }
171-
172- if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(parv[parc - 1],"\001ACTION ",8))
173- for (ch=parv[parc - 1];*ch;)
174- if (*ch++==1) {
175- return 0;
176- }
177+ if (client_can_send_to_channel(sptr, chptr, 0) &&
178+ !(chptr->mode.mode & MODE_NONOTICE) && /* +N check */
179+ (client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, parv[parc - 1], 0))) { /* +cC checks */
180
181 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
182 check_target_limit(sptr, chptr, chptr->chname, 0))
d2d7c538 183diff -r e80591f05c47 ircd/m_wallvoices.c
184--- a/ircd/m_wallvoices.c Sat Mar 20 17:57:13 2010 +0100
a42ed697 185+++ b/ircd/m_wallvoices.c Sun Mar 21 15:49:28 2010 +0100
97b63806 186@@ -102,7 +102,6 @@
187 {
188 struct Channel *chptr;
189 struct Membership* member;
190- const char *ch;
191
192 assert(0 != cptr);
193 assert(cptr == sptr);
194@@ -116,20 +115,9 @@
195 return send_reply(sptr, ERR_NOTEXTTOSEND);
196
197 if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) {
198- if (client_can_send_to_channel(sptr, chptr, 0) && !(chptr->mode.mode & MODE_NONOTICE)) {
199-
200- /* +cC checks */
201- if (chptr->mode.mode & MODE_NOCOLOUR)
202- for (ch=parv[parc - 1];*ch;ch++)
203- if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) {
204- return 0;
205- }
206-
207- if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(parv[parc - 1],"\001ACTION ",8))
208- for (ch=parv[parc - 1];*ch;)
209- if (*ch++==1) {
210- return 0;
211- }
212+ if (client_can_send_to_channel(sptr, chptr, 0) &&
213+ !(chptr->mode.mode & MODE_NONOTICE) && /* +N check */
214+ (client_can_send_controlcode_or_ctcp_to_channel(sptr, chptr, parv[parc - 1], 0))) { /* +cC checks */
215
216 if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
217 check_target_limit(sptr, chptr, chptr->chname, 0))