]>
Commit | Line | Data |
---|---|---|
4f141ee4 CP |
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 | ||
3975cc60 P |
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 @@ | |
4f141ee4 CP |
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 */ | |
3975cc60 P |
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 | |
4f141ee4 CP |
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. */ | |
71fa3149 | 22 | -#define infousermodes "dioOswkghxRXInP" |
23 | +#define infousermodes "dioOswkghxRXInPq" | |
4f141ee4 CP |
24 | |
25 | /** Character to indicate no oper name available */ | |
26 | #define NOOPERNAMECHARACTER '-' | |
0aefff88 | 27 | @@ -191,6 +191,8 @@ |
28 | FLAG_NOCHAN, /**< user's channels are hidden */ | |
4f141ee4 CP |
29 | FLAG_NOIDLE, /**< user's idletime is hidden */ |
30 | FLAG_XTRAOP, /**< oper has special powers */ | |
4f141ee4 CP |
31 | + FLAG_COMMONCHANSONLY, /**< SNIRCD_q: hide privmsgs/notices if in no |
32 | + common channels (with +ok exceptions) */ | |
0aefff88 | 33 | |
4f141ee4 CP |
34 | FLAG_LAST_FLAG, /**< number of flags */ |
35 | FLAG_LOCAL_UMODES = FLAG_LOCOP, /**< First local mode flag */ | |
0aefff88 | 36 | @@ -623,6 +625,8 @@ |
4f141ee4 CP |
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)) | |
0aefff88 | 45 | @@ -689,6 +693,8 @@ |
4f141ee4 CP |
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) \ | |
0aefff88 | 54 | @@ -738,6 +744,8 @@ |
4f141ee4 CP |
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 */ | |
3975cc60 P |
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 | |
71fa3149 | 66 | @@ -420,6 +420,7 @@ |
4f141ee4 CP |
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 | ||
3975cc60 P |
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 | |
0aefff88 | 77 | @@ -3819,3 +3819,39 @@ |
4f141ee4 CP |
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 | +} | |
3975cc60 P |
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 | |
71fa3149 | 120 | @@ -310,6 +310,10 @@ |
4f141ee4 | 121 | if (IsAccountOnly(acptr) && !IsAccount(sptr) && !IsXtraOp(sptr)) |
3975cc60 | 122 | return; |
4f141ee4 CP |
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 | } | |
71fa3149 | 131 | @@ -362,6 +366,9 @@ |
4f141ee4 CP |
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 | } | |
71fa3149 | 141 | @@ -401,6 +408,11 @@ |
0e4dc969 P |
142 | return; |
143 | } | |
4f141ee4 | 144 | |
0e4dc969 P |
145 | + if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1)) { |
146 | + send_reply(sptr, ERR_COMMONCHANSONLY, cli_name(acptr)); | |
4f141ee4 CP |
147 | + return; |
148 | + } | |
149 | + | |
0e4dc969 P |
150 | /* |
151 | * send away message if user away | |
88a737db | 152 | */ |
71fa3149 | 153 | @@ -445,6 +457,9 @@ |
88a737db | 154 | if (IsAccountOnly(acptr) && !IsAccount(sptr) && !IsXtraOp(sptr)) |
88a737db | 155 | return; |
156 | ||
0e4dc969 P |
157 | + if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1)) |
158 | + return; | |
159 | + | |
4f141ee4 | 160 | /* |
0e4dc969 P |
161 | * deliver the message |
162 | */ | |
3975cc60 P |
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 | |
4f141ee4 CP |
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 | ||
3975cc60 P |
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 | |
4f141ee4 CP |
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 */ | |
3975cc60 P |
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 | |
71fa3149 | 191 | @@ -540,7 +540,8 @@ |
4f141ee4 CP |
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. */ | |
71fa3149 | 201 | @@ -851,7 +852,9 @@ |
0e4dc969 | 202 | send_reply(source, ERR_ACCOUNTONLY, cli_name(dest), feature_str(FEAT_URLREG)); |
4f141ee4 CP |
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 | |
71fa3149 | 212 | @@ -1319,6 +1322,12 @@ |
4f141ee4 CP |
213 | else |
214 | ClearParanoid(sptr); | |
0e4dc969 | 215 | break; |
4f141ee4 CP |
216 | + case 'q': |
217 | + if (what == MODE_ADD) | |
218 | + SetCommonChansOnly(sptr); | |
219 | + else | |
220 | + ClearCommonChansOnly(sptr); | |
0e4dc969 | 221 | + break; |
4f141ee4 CP |
222 | case 'r': |
223 | if ((what == MODE_ADD) && *(p + 1)) { | |
0e4dc969 | 224 | account = *(++p); |