]>
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 3825aab95440 include/channel.h | |
6 | --- a/include/channel.h Mon Aug 10 14:18:18 2009 +0100 | |
7 | +++ b/include/channel.h Mon Aug 10 14:18:25 2009 +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 3825aab95440 include/client.h | |
16 | --- a/include/client.h Mon Aug 10 14:18:18 2009 +0100 | |
17 | +++ b/include/client.h Mon Aug 10 14:18:25 2009 +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 "dioOswkgxRXInP" | |
23 | +#define infousermodes "dioOswkgxRXInPq" | |
24 | ||
25 | /** Character to indicate no oper name available */ | |
26 | #define NOOPERNAMECHARACTER '-' | |
27 | @@ -194,7 +194,8 @@ | |
28 | FLAG_NOIDLE, /**< user's idletime is hidden */ | |
29 | FLAG_XTRAOP, /**< oper has special powers */ | |
30 | FLAG_OPERNAME, /**< Server sends oper name in mode string */ | |
31 | - | |
32 | + FLAG_COMMONCHANSONLY, /**< SNIRCD_q: hide privmsgs/notices if in no | |
33 | + common channels (with +ok exceptions) */ | |
34 | FLAG_LAST_FLAG, /**< number of flags */ | |
35 | FLAG_LOCAL_UMODES = FLAG_LOCOP, /**< First local mode flag */ | |
36 | FLAG_GLOBAL_UMODES = FLAG_OPER /**< First global mode flag */ | |
37 | @@ -626,6 +627,8 @@ | |
38 | #define IsParanoid(x) HasFlag(x, FLAG_PARANOID) | |
39 | /** Return non-zero if the server should send opername information */ | |
40 | #define IsSendOperName(x) HasFlag(x, FLAG_OPERNAME) | |
41 | +/** Return non-zero if the client has set mode +q (common chans only). */ | |
42 | +#define IsCommonChansOnly(x) HasFlag(x, FLAG_COMMONCHANSONLY) | |
43 | ||
44 | /** Return non-zero if the client has operator or server privileges. */ | |
45 | #define IsPrivileged(x) (IsAnOper(x) || IsServer(x)) | |
46 | @@ -689,6 +692,8 @@ | |
47 | #define SetAccountOnly(x) SetFlag(x, FLAG_ACCOUNTONLY) | |
48 | /** Mark a client as having mode +P (paranoid). */ | |
49 | #define SetParanoid(x) SetFlag(x, FLAG_PARANOID) | |
50 | +/** Mark a client as having mode +q (common chans only). */ | |
51 | +#define SetCommonChansOnly(x) SetFlag(x, FLAG_COMMONCHANSONLY) | |
52 | ||
53 | /** Return non-zero if \a sptr sees \a acptr as an operator. */ | |
54 | #define SeeOper(sptr,acptr) (IsAnOper(acptr) && (HasPriv(acptr, PRIV_DISPLAY) \ | |
55 | @@ -736,6 +741,8 @@ | |
56 | #define ClearAccountOnly(x) ClrFlag(x, FLAG_ACCOUNTONLY) | |
57 | /** Remove mode +P (paranoid) from a client */ | |
58 | #define ClearParanoid(x) ClrFlag(x, FLAG_PARANOID) | |
59 | +/** Remove mode +q (common chans only) from a client */ | |
60 | +#define ClearCommonChansOnly(x) ClrFlag(x, FLAG_COMMONCHANSONLY) | |
61 | ||
62 | /* free flags */ | |
63 | #define FREEFLAG_SOCKET 0x0001 /**< socket needs to be freed */ | |
64 | diff -r 3825aab95440 include/numeric.h | |
65 | --- a/include/numeric.h Mon Aug 10 14:18:18 2009 +0100 | |
66 | +++ b/include/numeric.h Mon Aug 10 14:18:25 2009 +0100 | |
67 | @@ -421,6 +421,7 @@ | |
68 | /* ERR_HTMDISABLED 486 unreal */ | |
69 | #define ERR_ACCOUNTONLY 486 /* QuakeNet/ASUKA extension */ | |
70 | /* ERR_CHANTOORECENT 487 IRCnet extension (?) */ | |
71 | +#define ERR_COMMONCHANSONLY 487 /* QuakeNet/snircd extension */ | |
72 | /* ERR_TSLESSCHAN 488 IRCnet extension (?) */ | |
73 | #define ERR_VOICENEEDED 489 /* Undernet extension */ | |
74 | ||
75 | diff -r 3825aab95440 ircd/channel.c | |
76 | --- a/ircd/channel.c Mon Aug 10 14:18:18 2009 +0100 | |
77 | +++ b/ircd/channel.c Mon Aug 10 14:18:25 2009 +0100 | |
78 | @@ -3804,3 +3804,39 @@ | |
79 | ||
80 | return marker; | |
81 | } | |
82 | + | |
83 | +/* Returns the number of common channels between two users, upto max. */ | |
84 | +int common_chan_count(struct Client *a, struct Client *b, int max) | |
85 | +{ | |
86 | + int count = 0; | |
87 | + struct Membership *cptr; | |
88 | + struct User *ua, *ub; | |
89 | + unsigned int marker = get_client_marker(); | |
90 | + | |
91 | + ua = cli_user(a); | |
92 | + ub = cli_user(b); | |
93 | + | |
94 | + /* makes no difference to the big O complexity I know */ | |
95 | + if(ua->joined > ub->joined) | |
96 | + { | |
97 | + struct User *swapee = ua; | |
98 | + ua = ub; | |
99 | + ub = swapee; | |
100 | + } | |
101 | + | |
102 | + for (cptr=ua->channel;cptr;cptr=cptr->next_channel) | |
103 | + { | |
104 | + cptr->channel->marker = marker; | |
105 | + } | |
106 | + | |
107 | + for (cptr=ub->channel;cptr;cptr=cptr->next_channel) | |
108 | + { | |
109 | + if (cptr->channel->marker == marker) { | |
110 | + count++; | |
111 | + if (max && (count >= max)) | |
112 | + return count; | |
113 | + } | |
114 | + } | |
115 | + | |
116 | + return count; | |
117 | +} | |
118 | diff -r 3825aab95440 ircd/ircd_relay.c | |
119 | --- a/ircd/ircd_relay.c Mon Aug 10 14:18:18 2009 +0100 | |
120 | +++ b/ircd/ircd_relay.c Mon Aug 10 14:18:25 2009 +0100 | |
121 | @@ -309,6 +309,10 @@ | |
122 | if (IsAccountOnly(acptr) && !IsAccount(sptr) && !IsXtraOp(sptr)) | |
123 | return; | |
124 | ||
125 | + /* slug: same applies here, since only opers can be +k */ | |
126 | + if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1)) | |
127 | + return; | |
128 | + | |
129 | if (!(is_silenced(sptr, acptr))) | |
130 | sendcmdto_one(sptr, CMD_PRIVATE, acptr, "%s :%s", name, text); | |
131 | } | |
132 | @@ -361,6 +365,9 @@ | |
133 | if (IsAccountOnly(acptr) && !IsAccount(sptr) && !IsXtraOp(sptr)) | |
134 | return; | |
135 | ||
136 | + if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1)) | |
137 | + return; | |
138 | + | |
139 | if (!(is_silenced(sptr, acptr))) | |
140 | sendcmdto_one(sptr, CMD_NOTICE, acptr, "%s :%s", name, text); | |
141 | } | |
142 | @@ -400,6 +407,11 @@ | |
143 | return; | |
144 | } | |
145 | ||
146 | + if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1)) { | |
147 | + send_reply(sptr, ERR_COMMONCHANSONLY, cli_name(acptr)); | |
148 | + return; | |
149 | + } | |
150 | + | |
151 | /* | |
152 | * send away message if user away | |
153 | */ | |
154 | @@ -444,6 +456,9 @@ | |
155 | if (IsAccountOnly(acptr) && !IsAccount(sptr) && !IsXtraOp(sptr)) | |
156 | return; | |
157 | ||
158 | + if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1)) | |
159 | + return; | |
160 | + | |
161 | /* | |
162 | * deliver the message | |
163 | */ | |
164 | diff -r 3825aab95440 ircd/m_invite.c | |
165 | --- a/ircd/m_invite.c Mon Aug 10 14:18:18 2009 +0100 | |
166 | +++ b/ircd/m_invite.c Mon Aug 10 14:18:25 2009 +0100 | |
167 | @@ -171,6 +171,9 @@ | |
168 | return 0; | |
169 | } | |
170 | ||
171 | + if (IsCommonChansOnly(acptr) && !IsXtraOp(sptr) && !common_chan_count(acptr, sptr, 1)) | |
172 | + return; | |
173 | + | |
174 | if (check_target_limit(sptr, acptr, cli_name(acptr), 0)) | |
175 | return 0; | |
176 | ||
177 | diff -r 3825aab95440 ircd/s_err.c | |
178 | --- a/ircd/s_err.c Mon Aug 10 14:18:18 2009 +0100 | |
179 | +++ b/ircd/s_err.c Mon Aug 10 14:18:25 2009 +0100 | |
180 | @@ -1006,7 +1006,7 @@ | |
181 | /* 486 */ | |
182 | { ERR_ACCOUNTONLY, "%s :You must be authed in order to message this user -- For details of how to obtain an account visit %s", "486" }, | |
183 | /* 487 */ | |
184 | - { 0 }, | |
185 | + { ERR_COMMONCHANSONLY, "%s :You must share at least one channel with this user in order to message them", "487" }, | |
186 | /* 488 */ | |
187 | { 0 }, | |
188 | /* 489 */ | |
189 | diff -r 3825aab95440 ircd/s_user.c | |
190 | --- a/ircd/s_user.c Mon Aug 10 14:18:18 2009 +0100 | |
191 | +++ b/ircd/s_user.c Mon Aug 10 14:18:25 2009 +0100 | |
192 | @@ -546,7 +546,8 @@ | |
193 | { FLAG_NOCHAN, 'n' }, | |
194 | { FLAG_NOIDLE, 'I' }, | |
195 | { FLAG_SETHOST, 'h' }, | |
196 | - { FLAG_PARANOID, 'P' } | |
197 | + { FLAG_PARANOID, 'P' }, | |
198 | + { FLAG_COMMONCHANSONLY, 'q' } | |
199 | }; | |
200 | ||
201 | /** Length of #userModeList. */ | |
202 | @@ -857,7 +858,9 @@ | |
203 | send_reply(source, ERR_ACCOUNTONLY, cli_name(dest), feature_str(FEAT_URLREG)); | |
204 | return 0; | |
205 | } | |
206 | - | |
207 | + | |
208 | + /* No check here for IsCommonChansOnly since by definition we share at least one! */ | |
209 | + | |
210 | if (is_notice) | |
211 | sendcmdto_one(source, CMD_NOTICE, dest, "%C :%s", dest, text); | |
212 | else | |
213 | @@ -1429,6 +1432,12 @@ | |
214 | else | |
215 | ClearParanoid(sptr); | |
216 | break; | |
217 | + case 'q': | |
218 | + if (what == MODE_ADD) | |
219 | + SetCommonChansOnly(sptr); | |
220 | + else | |
221 | + ClearCommonChansOnly(sptr); | |
222 | + break; | |
223 | case 'r': | |
224 | if ((what == MODE_ADD) && *(p + 1)) { | |
225 | account = *(++p); |