ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/modules/m_whois.c
Revision: 9156
Committed: Mon Jan 13 14:51:47 2020 UTC (6 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 10782 byte(s)
Log Message:
- Replaced most occurences of 'SSL' with 'TLS'

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
4 * Copyright (c) 1997-2020 ircd-hybrid development team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 * USA
20 */
21
22 /*! \file m_whois.c
23 * \brief Includes required functions for processing the WHOIS command.
24 * \version $Id$
25 */
26
27 #include "stdinc.h"
28 #include "list.h"
29 #include "client.h"
30 #include "client_svstag.h"
31 #include "hash.h"
32 #include "channel.h"
33 #include "channel_mode.h"
34 #include "ircd.h"
35 #include "numeric.h"
36 #include "conf.h"
37 #include "misc.h"
38 #include "server.h"
39 #include "user.h"
40 #include "send.h"
41 #include "irc_string.h"
42 #include "parse.h"
43 #include "modules.h"
44
45
46 static int
47 whois_can_see_channels(struct Channel *channel,
48 struct Client *source_p,
49 struct Client *target_p)
50 {
51 if (PubChannel(channel) && !HasUMode(target_p, UMODE_HIDECHANS))
52 return 1;
53
54 if (source_p == target_p || IsMember(source_p, channel))
55 return 1;
56
57 if (HasUMode(source_p, UMODE_OPER))
58 return 2;
59 return 0;
60 }
61
62 /* whois_person()
63 *
64 * inputs - source_p client to report to
65 * - target_p client to report on
66 * output - NONE
67 * side effects -
68 */
69 static void
70 whois_person(struct Client *source_p, struct Client *target_p)
71 {
72 char buf[IRCD_BUFSIZE] = "";
73 dlink_node *node;
74 const struct ServicesTag *svstag = NULL;
75 char *t = NULL;
76 int cur_len = 0;
77 int mlen = 0;
78 int tlen = 0;
79 int reply_to_send = 0;
80
81 sendto_one_numeric(source_p, &me, RPL_WHOISUSER, target_p->name,
82 target_p->username, target_p->host,
83 target_p->info);
84
85 cur_len = mlen = snprintf(buf, sizeof(buf), numeric_form(RPL_WHOISCHANNELS),
86 me.name, source_p->name, target_p->name, "");
87 t = buf + mlen;
88
89 DLINK_FOREACH(node, target_p->channel.head)
90 {
91 const struct ChannelMember *member = node->data;
92 int show = whois_can_see_channels(member->channel, source_p, target_p);
93
94 if (show)
95 {
96 if ((cur_len + 4 + member->channel->name_len + 1) > (IRCD_BUFSIZE - 2))
97 {
98 *(t - 1) = '\0';
99 sendto_one(source_p, "%s", buf);
100 cur_len = mlen;
101 t = buf + mlen;
102 }
103
104 tlen = sprintf(t, "%s%s%s ", show == 2 ? "~" : "", get_member_status(member, true),
105 member->channel->name);
106 t += tlen;
107 cur_len += tlen;
108 reply_to_send = 1;
109 }
110 }
111
112 if (reply_to_send)
113 {
114 *(t - 1) = '\0';
115 sendto_one(source_p, "%s", buf);
116 }
117
118 if ((ConfigServerHide.hide_servers || IsHidden(target_p->servptr)) &&
119 !(HasUMode(source_p, UMODE_OPER) || source_p == target_p))
120 sendto_one_numeric(source_p, &me, RPL_WHOISSERVER, target_p->name,
121 ConfigServerHide.hidden_name,
122 ConfigServerInfo.network_desc);
123 else
124 sendto_one_numeric(source_p, &me, RPL_WHOISSERVER, target_p->name,
125 target_p->servptr->name, target_p->servptr->info);
126
127 if (HasUMode(target_p, UMODE_REGISTERED))
128 sendto_one_numeric(source_p, &me, RPL_WHOISREGNICK, target_p->name);
129
130 if (strcmp(target_p->account, "*"))
131 sendto_one_numeric(source_p, &me, RPL_WHOISACCOUNT, target_p->name,
132 target_p->account, "is");
133
134 if (target_p->away[0])
135 sendto_one_numeric(source_p, &me, RPL_AWAY, target_p->name,
136 target_p->away);
137
138 if (HasUMode(target_p, UMODE_CALLERID | UMODE_SOFTCALLERID))
139 {
140 bool callerid = HasUMode(target_p, UMODE_CALLERID) != 0;
141
142 sendto_one_numeric(source_p, &me, RPL_TARGUMODEG, target_p->name,
143 callerid ? "+g" : "+G",
144 callerid ? "server side ignore" :
145 "server side ignore with the exception of common channels");
146 }
147
148 if (HasUMode(target_p, UMODE_OPER) || HasFlag(target_p, FLAGS_SERVICE))
149 {
150 if (!HasUMode(target_p, UMODE_HIDDEN) || HasUMode(source_p, UMODE_OPER))
151 {
152 if (target_p->svstags.head)
153 svstag = target_p->svstags.head->data;
154
155 if (svstag == NULL || svstag->numeric != RPL_WHOISOPERATOR)
156 {
157 const char *text;
158 if (HasFlag(target_p, FLAGS_SERVICE))
159 text = "is a Network Service";
160 else if (HasUMode(target_p, UMODE_ADMIN))
161 text = "is a Server Administrator";
162 else /* HasUMode(target_p, UMODE_OPER) == true */
163 text = "is an IRC Operator";
164 sendto_one_numeric(source_p, &me, RPL_WHOISOPERATOR, target_p->name, text);
165 }
166 }
167 }
168
169 DLINK_FOREACH(node, target_p->svstags.head)
170 {
171 svstag = node->data;
172
173 if (svstag->numeric == RPL_WHOISOPERATOR)
174 if (HasUMode(target_p, UMODE_HIDDEN) && !HasUMode(source_p, UMODE_OPER))
175 continue;
176
177 if (svstag->umodes == 0 || HasUMode(source_p, svstag->umodes))
178 sendto_one_numeric(source_p, &me, svstag->numeric | SND_EXPLICIT, "%s :%s",
179 target_p->name, svstag->tag);
180 }
181
182 if (HasUMode(target_p, UMODE_WEBIRC))
183 sendto_one_numeric(source_p, &me, RPL_WHOISTEXT, target_p->name,
184 "User connected using a webirc gateway");
185
186 if (HasUMode(source_p, UMODE_OPER) || source_p == target_p)
187 {
188 char *m = buf;
189 *m++ = '+';
190
191 for (const struct user_modes *tab = umode_tab; tab->c; ++tab)
192 if (HasUMode(target_p, tab->flag))
193 *m++ = tab->c;
194 *m = '\0';
195
196 sendto_one_numeric(source_p, &me, RPL_WHOISMODES, target_p->name, buf);
197 }
198
199 if (HasUMode(source_p, UMODE_OPER) || source_p == target_p)
200 sendto_one_numeric(source_p, &me, RPL_WHOISACTUALLY, target_p->name,
201 target_p->username, target_p->realhost,
202 target_p->sockhost);
203
204 if (HasUMode(target_p, UMODE_SECURE))
205 sendto_one_numeric(source_p, &me, RPL_WHOISSECURE, target_p->name);
206
207 if (!EmptyString(target_p->certfp))
208 if (HasUMode(source_p, UMODE_OPER) || source_p == target_p)
209 sendto_one_numeric(source_p, &me, RPL_WHOISCERTFP, target_p->name, target_p->certfp);
210
211 if (MyConnect(target_p))
212 if (!HasUMode(target_p, UMODE_HIDEIDLE) || HasUMode(source_p, UMODE_OPER) ||
213 source_p == target_p)
214 sendto_one_numeric(source_p, &me, RPL_WHOISIDLE, target_p->name,
215 client_get_idle_time(source_p, target_p),
216 target_p->connection->created_real);
217
218 if (HasUMode(target_p, UMODE_SPY) && source_p != target_p)
219 sendto_one_notice(target_p, &me, ":*** Notice -- %s (%s@%s) [%s] is doing a /whois on you",
220 source_p->name, source_p->username, source_p->host, source_p->servptr->name);
221 }
222
223 /* do_whois()
224 *
225 * inputs - pointer to /whois source
226 * - number of parameters
227 * - pointer to parameters array
228 * output - pointer to void
229 * side effects - Does whois
230 */
231 static void
232 do_whois(struct Client *source_p, const char *name)
233 {
234 struct Client *target_p;
235
236 if ((target_p = hash_find_client(name)) && IsClient(target_p))
237 whois_person(source_p, target_p);
238 else
239 sendto_one_numeric(source_p, &me, ERR_NOSUCHNICK, name);
240
241 sendto_one_numeric(source_p, &me, RPL_ENDOFWHOIS, name);
242 }
243
244 /*! \brief WHOIS command handler
245 *
246 * \param source_p Pointer to allocated Client struct from which the message
247 * originally comes from. This can be a local or remote client.
248 * \param parc Integer holding the number of supplied arguments.
249 * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
250 * pointers.
251 * \note Valid arguments for this command are:
252 * - parv[0] = command
253 * - parv[1] = nickname/servername
254 * - parv[2] = nickname
255 */
256 static void
257 m_whois(struct Client *source_p, int parc, char *parv[])
258 {
259 static uintmax_t last_used = 0;
260
261 if (parc < 2 || EmptyString(parv[1]))
262 {
263 sendto_one_numeric(source_p, &me, ERR_NONICKNAMEGIVEN);
264 return;
265 }
266
267 if (parc > 2 && !EmptyString(parv[2]))
268 {
269 /* seeing as this is going across servers, we should limit it */
270 if ((last_used + ConfigGeneral.pace_wait_simple) > event_base->time.sec_monotonic)
271 {
272 sendto_one_numeric(source_p, &me, RPL_LOAD2HI, "WHOIS");
273 return;
274 }
275
276 last_used = event_base->time.sec_monotonic;
277
278 /*
279 * if we have serverhide enabled, they can either ask the clients
280 * server, or our server.. I don't see why they would need to ask
281 * anything else for info about the client.. --fl_
282 */
283 if (ConfigServerHide.disable_remote_commands)
284 parv[1] = parv[2];
285
286 if (server_hunt(source_p, ":%s WHOIS %s :%s", 1, parc, parv)->ret != HUNTED_ISME)
287 return;
288
289 parv[1] = parv[2];
290 }
291
292 do_whois(source_p, parv[1]);
293 }
294
295 /*! \brief WHOIS command handler
296 *
297 * \param source_p Pointer to allocated Client struct from which the message
298 * originally comes from. This can be a local or remote client.
299 * \param parc Integer holding the number of supplied arguments.
300 * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
301 * pointers.
302 * \note Valid arguments for this command are:
303 * - parv[0] = command
304 * - parv[1] = nickname/servername
305 * - parv[2] = nickname
306 */
307 static void
308 mo_whois(struct Client *source_p, int parc, char *parv[])
309 {
310 if (parc < 2 || EmptyString(parv[1]))
311 {
312 sendto_one_numeric(source_p, &me, ERR_NONICKNAMEGIVEN);
313 return;
314 }
315
316 if (parc > 2 && !EmptyString(parv[2]))
317 {
318 if (server_hunt(source_p, ":%s WHOIS %s :%s", 1, parc, parv)->ret != HUNTED_ISME)
319 return;
320
321 parv[1] = parv[2];
322 }
323
324 do_whois(source_p, parv[1]);
325 }
326
327 static struct Message whois_msgtab =
328 {
329 .cmd = "WHOIS",
330 .args_max = MAXPARA,
331 .handlers[UNREGISTERED_HANDLER] = m_unregistered,
332 .handlers[CLIENT_HANDLER] = m_whois,
333 .handlers[SERVER_HANDLER] = mo_whois,
334 .handlers[ENCAP_HANDLER] = m_ignore,
335 .handlers[OPER_HANDLER] = mo_whois
336 };
337
338 static void
339 module_init(void)
340 {
341 mod_add_cmd(&whois_msgtab);
342 }
343
344 static void
345 module_exit(void)
346 {
347 mod_del_cmd(&whois_msgtab);
348 }
349
350 struct module module_entry =
351 {
352 .version = "$Revision$",
353 .modinit = module_init,
354 .modexit = module_exit,
355 };

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision