]>
Commit | Line | Data |
---|---|---|
1 | Add usermode +q which requires users /msg'ing or /notice'ing you to be in at least one common channel. | |
2 | This is designed to stop the spam bots which sit outside a channel, while a spy sits inside, preventing channel operators dealing with the problem. | |
3 | We currently also block invites, this might not be such a good idea, but these days everyone can get Q. | |
4 | ||
5 | diff -r 5787dbfaa811 include/channel.h | |
6 | --- a/include/channel.h Sat Jul 20 11:50:29 2013 +0100 | |
7 | +++ b/include/channel.h Sat Jul 20 11:50:33 2013 +0100 | |
8 | @@ -463,5 +463,6 @@ | |
9 | extern void free_ban(struct Ban *ban); | |
10 | ||
11 | extern unsigned int get_channel_marker(void); | |
12 | +extern int common_chan_count(struct Client *a, struct Client *b, int max); | |
13 | ||
14 | #endif /* INCLUDED_channel_h */ | |
15 | diff -r 5787dbfaa811 include/client.h | |
16 | --- a/include/client.h Sat Jul 20 11:50:29 2013 +0100 | |
17 | +++ b/include/client.h Sat Jul 20 11:50:33 2013 +0100 | |
18 | @@ -90,7 +90,7 @@ | |
19 | #define FlagClr(set,flag) ((set)->bits[FLAGSET_INDEX(flag)] &= ~FLAGSET_MASK(flag)) | |
20 | ||
21 | /** String containing valid user modes, in no particular order. */ | |
22 | -#define infousermodes "dioOswkghxRXInP" | |
23 | +#define infousermodes "dioOswkghxRXInPq" | |
24 | ||
25 | /** Character to indicate no oper name available */ | |
26 | #define NOOPERNAMECHARACTER '-' | |
27 | @@ -191,6 +191,8 @@ | |
28 | FLAG_NOCHAN, /**< user's channels are hidden */ | |
29 | FLAG_NOIDLE, /**< user's idletime is hidden */ | |
30 | FLAG_XTRAOP, /**< oper has special powers */ | |
31 | + FLAG_COMMONCHANSONLY, /**< SNIRCD_q: hide privmsgs/notices if in no | |
32 | + common channels (with +ok exceptions) */ | |
33 | ||
34 | FLAG_LAST_FLAG, /**< number of flags */ | |
35 | FLAG_LOCAL_UMODES = FLAG_LOCOP, /**< First local mode flag */ | |
36 | @@ -623,6 +625,8 @@ | |
37 | #define IsParanoid(x) HasFlag(x, FLAG_PARANOID) | |
38 | /** Return non-zero if the server should send opername information */ | |
39 | #define IsSendOperName(x) HasFlag(x, FLAG_OPERNAME) | |
40 | +/** Return non-zero if the client has set mode +q (common chans only). */ | |
41 | +#define IsCommonChansOnly(x) HasFlag(x, FLAG_COMMONCHANSONLY) | |
42 | ||
43 | /** Return non-zero if the client has operator or server privileges. */ | |
44 | #define IsPrivileged(x) (IsAnOper(x) || IsServer(x)) | |
45 | @@ -689,6 +693,8 @@ | |
46 | #define SetAccountOnly(x) SetFlag(x, FLAG_ACCOUNTONLY) | |
47 | /** Mark a client as having mode +P (paranoid). */ | |
48 | #define SetParanoid(x) SetFlag(x, FLAG_PARANOID) | |
49 | +/** Mark a client as having mode +q (common chans only). */ | |
50 | +#define SetCommonChansOnly(x) SetFlag(x, FLAG_COMMONCHANSONLY) | |
51 | ||
52 | /** Return non-zero if \a sptr sees \a acptr as an operator. */ | |
53 | #define SeeOper(sptr,acptr) (IsAnOper(acptr) && (HasPriv(acptr, PRIV_DISPLAY) \ | |
54 | @@ -738,6 +744,8 @@ | |
55 | #define ClearAccountOnly(x) ClrFlag(x, FLAG_ACCOUNTONLY) | |
56 | /** Remove mode +P (paranoid) from a client */ | |
57 | #define ClearParanoid(x) ClrFlag(x, FLAG_PARANOID) | |
58 | +/** Remove mode +q (common chans only) from a client */ | |
59 | +#define ClearCommonChansOnly(x) ClrFlag(x, FLAG_COMMONCHANSONLY) | |
60 | ||
61 | /* free flags */ | |
62 | #define FREEFLAG_SOCKET 0x0001 /**< socket needs to be freed */ | |
63 | diff -r 5787dbfaa811 include/numeric.h | |
64 | --- a/include/numeric.h Sat Jul 20 11:50:29 2013 +0100 | |
65 | +++ b/include/numeric.h Sat Jul 20 11:50:33 2013 +0100 | |
66 | @@ -420,6 +420,7 @@ | |
67 | /* ERR_HTMDISABLED 486 unreal */ | |
68 | #define ERR_ACCOUNTONLY 486 /* QuakeNet/ASUKA extension */ | |
69 | /* ERR_CHANTOORECENT 487 IRCnet extension (?) */ | |
70 | +#define ERR_COMMONCHANSONLY 487 /* QuakeNet/snircd extension */ | |
71 | /* ERR_TSLESSCHAN 488 IRCnet extension (?) */ | |
72 | #define ERR_VOICENEEDED 489 /* Undernet extension */ | |
73 | ||
74 | diff -r 5787dbfaa811 ircd/channel.c | |
75 | --- a/ircd/channel.c Sat Jul 20 11:50:29 2013 +0100 | |
76 | +++ b/ircd/channel.c Sat Jul 20 11:50:33 2013 +0100 | |
77 | @@ -3819,3 +3819,39 @@ | |
78 | ||
79 | return marker; | |
80 | } | |
81 | + | |
82 | +/* Returns the number of common channels between two users, upto max. */ | |
83 | +int common_chan_count(struct Client *a, struct Client *b, int max) | |
84 | +{ | |
85 | + int count = 0; | |
86 | + struct Membership *cptr; | |
87 | + struct User *ua, *ub; | |
88 | + unsigned int marker = get_client_marker(); | |
89 | + | |
90 | + ua = cli_user(a); | |
91 | + ub = cli_user(b); | |
92 | + | |
93 | + /* makes no difference to the big O complexity I know */ | |
94 | + if(ua->joined > ub->joined) | |
95 | + { | |
96 | + struct User *swapee = ua; | |
97 | + ua = ub; | |
98 | + ub = swapee; | |
99 | + } | |
100 | + | |
101 | + for (cptr=ua->channel;cptr;cptr=cptr->next_channel) | |
102 | + { | |
103 | + cptr->channel->marker = marker; | |
104 | + } | |
105 | + | |
106 | + for (cptr=ub->channel;cptr;cptr=cptr->next_channel) | |
107 | + { | |
108 | + if (cptr->channel->marker == marker) { | |
109 | + count++; | |
110 | + if (max && (count >= max)) | |
111 | + return count; | |
112 | + } | |
113 | + } | |
114 | + | |
115 | + return count; | |
116 | +} | |
117 | diff -r 5787dbfaa811 ircd/ircd_relay.c | |
118 | --- a/ircd/ircd_relay.c Sat Jul 20 11:50:29 2013 +0100 | |
119 | +++ b/ircd/ircd_relay.c Sat Jul 20 11:50:33 2013 +0100 | |
120 | @@ -310,6 +310,10 @@ | |
121 | if (IsAccountOnly(acptr) && !IsAccount(sptr) && !IsXtraOp(sptr)) | |
122 | return; | |
123 | ||
124 | + /* slug: same applies here, since only opers can be +k */ | |
125 | + if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1)) | |
126 | + return; | |
127 | + | |
128 | if (!(is_silenced(sptr, acptr))) | |
129 | sendcmdto_one(sptr, CMD_PRIVATE, acptr, "%s :%s", name, text); | |
130 | } | |
131 | @@ -362,6 +366,9 @@ | |
132 | if (IsAccountOnly(acptr) && !IsAccount(sptr) && !IsXtraOp(sptr)) | |
133 | return; | |
134 | ||
135 | + if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1)) | |
136 | + return; | |
137 | + | |
138 | if (!(is_silenced(sptr, acptr))) | |
139 | sendcmdto_one(sptr, CMD_NOTICE, acptr, "%s :%s", name, text); | |
140 | } | |
141 | @@ -401,6 +408,11 @@ | |
142 | return; | |
143 | } | |
144 | ||
145 | + if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1)) { | |
146 | + send_reply(sptr, ERR_COMMONCHANSONLY, cli_name(acptr)); | |
147 | + return; | |
148 | + } | |
149 | + | |
150 | /* | |
151 | * send away message if user away | |
152 | */ | |
153 | @@ -445,6 +457,9 @@ | |
154 | if (IsAccountOnly(acptr) && !IsAccount(sptr) && !IsXtraOp(sptr)) | |
155 | return; | |
156 | ||
157 | + if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1)) | |
158 | + return; | |
159 | + | |
160 | /* | |
161 | * deliver the message | |
162 | */ | |
163 | diff -r 5787dbfaa811 ircd/m_invite.c | |
164 | --- a/ircd/m_invite.c Sat Jul 20 11:50:29 2013 +0100 | |
165 | +++ b/ircd/m_invite.c Sat Jul 20 11:50:33 2013 +0100 | |
166 | @@ -171,6 +171,9 @@ | |
167 | return 0; | |
168 | } | |
169 | ||
170 | + if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1)) | |
171 | + return; | |
172 | + | |
173 | if (check_target_limit(sptr, acptr, cli_name(acptr), 0)) | |
174 | return 0; | |
175 | ||
176 | diff -r 5787dbfaa811 ircd/s_err.c | |
177 | --- a/ircd/s_err.c Sat Jul 20 11:50:29 2013 +0100 | |
178 | +++ b/ircd/s_err.c Sat Jul 20 11:50:33 2013 +0100 | |
179 | @@ -1006,7 +1006,7 @@ | |
180 | /* 486 */ | |
181 | { ERR_ACCOUNTONLY, "%s :You must be authed in order to message this user -- For details of how to obtain an account visit %s", "486" }, | |
182 | /* 487 */ | |
183 | - { 0 }, | |
184 | + { ERR_COMMONCHANSONLY, "%s :You must share at least one channel with this user in order to message them", "487" }, | |
185 | /* 488 */ | |
186 | { 0 }, | |
187 | /* 489 */ | |
188 | diff -r 5787dbfaa811 ircd/s_user.c | |
189 | --- a/ircd/s_user.c Sat Jul 20 11:50:29 2013 +0100 | |
190 | +++ b/ircd/s_user.c Sat Jul 20 11:50:33 2013 +0100 | |
191 | @@ -540,7 +540,8 @@ | |
192 | { FLAG_NOCHAN, 'n' }, | |
193 | { FLAG_NOIDLE, 'I' }, | |
194 | { FLAG_SETHOST, 'h' }, | |
195 | - { FLAG_PARANOID, 'P' } | |
196 | + { FLAG_PARANOID, 'P' }, | |
197 | + { FLAG_COMMONCHANSONLY, 'q' } | |
198 | }; | |
199 | ||
200 | /** Length of #userModeList. */ | |
201 | @@ -851,7 +852,9 @@ | |
202 | send_reply(source, ERR_ACCOUNTONLY, cli_name(dest), feature_str(FEAT_URLREG)); | |
203 | return 0; | |
204 | } | |
205 | - | |
206 | + | |
207 | + /* No check here for IsCommonChansOnly since by definition we share at least one! */ | |
208 | + | |
209 | if (is_notice) | |
210 | sendcmdto_one(source, CMD_NOTICE, dest, "%C :%s", dest, text); | |
211 | else | |
212 | @@ -1319,6 +1322,12 @@ | |
213 | else | |
214 | ClearParanoid(sptr); | |
215 | break; | |
216 | + case 'q': | |
217 | + if (what == MODE_ADD) | |
218 | + SetCommonChansOnly(sptr); | |
219 | + else | |
220 | + ClearCommonChansOnly(sptr); | |
221 | + break; | |
222 | case 'r': | |
223 | if ((what == MODE_ADD) && *(p + 1)) { | |
224 | account = *(++p); |