1 /*
2  * ctcp.c:handles the client-to-client protocol(ctcp).
3  *
4  * Copyright (c) 1990 Michael Sandroff.
5  * Copyright (c) 1991, 1992 Troy Rollo.
6  * Copyright (c) 1992-1996 Matthew Green.
7  * Copyright 1993, 2018 EPIC Software Labs
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notices, the above paragraph (the one permitting redistribution),
17  *    this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. The names of the author(s) may not be used to endorse or promote
20  *    products derived from this software without specific prior written
21  *    permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 /* Major revamps in 1996 and 2018 */
36 
37 #include "irc.h"
38 #include "sedcrypt.h"
39 #include "ctcp.h"
40 #include "dcc.h"
41 #include "commands.h"
42 #include "hook.h"
43 #include "ignore.h"
44 #include "ircaux.h"
45 #include "lastlog.h"
46 #include "names.h"
47 #include "output.h"
48 #include "parse.h"
49 #include "server.h"
50 #include "status.h"
51 #include "vars.h"
52 #include "window.h"
53 #include "ifcmd.h"
54 #include "flood.h"
55 #include "words.h"
56 #include "functions.h"
57 
58 #include <pwd.h>
59 #ifdef HAVE_UNAME
60 # include <sys/utsname.h>
61 #endif
62 
63 /* CTCP BITFLAGS */
64 #define CTCP_SPECIAL	1	/* Special handlers handle everything and don't return anything */
65 #define CTCP_ORDINARY   2	/* Ordinary handlers either return a inline value or you should tell the user */
66 #define CTCP_REPLACE_ARGS   4	/* A "replace args" CTCP rewrites the args, but still needs to be "handled" normally */
67 #define CTCP_RAW	32	/* Requires the original payload, not a recoded message */
68 
69 /* CTCP ENTRIES */
70 /*
71  * A CTCP Entry lists the built in CTCPs
72  * Out of the box, the client comes with some CTCPs implemented as C functions.
73  * You can add your own CTCP handlers with ircII aliases.
74  *
75  * "Why should I register a CTCP handler rather than using /on ctcp_request?"
76  * you might ask.  There needs to be a way to script a CTCP handler that can
77  * expand inline (such as CTCP UTC), and there's no good way to do that with
78  * an /ON.
79  *
80  * CTCP Handlers (whether in C or ircII take 4 arguments:
81  *	$0 - The sender of the CTCP
82  *	$1 - The receiver of the CTCP (ie, you, or a channel)
83  *	$2 - The kind of CTCP (ie, ACTION or VERSION or DCC)
84  *	$3 - Arguments to the CTCP (not all CTCPs have arguments - can be NULL)
85  */
86 typedef char *(*CTCP_Handler) (const char *, const char *, const char *, char *);
87 typedef	struct _CtcpEntry
88 {
89 	int		flag;		/* Action modifiers */
90 	char *		desc;  		/* description returned by ctcp clientinfo */
91 	CTCP_Handler 	func;		/* C function to handle requests */
92 	CTCP_Handler 	repl;		/* C function to handle replies */
93 	char *		user_func;	/* Block of code to handle requests */
94 	char *		user_repl;	/* Block of code to handle replies */
95 }	CtcpEntry;
96 
97 /*
98  * Let's review buckets real quick...
99  * Buckets are an (insert-)ordered array of key-value pairs
100  *
101  * The bucket itself contains
102  *	numitems	-> The number of items in the bucket
103  *	list		-> An array of (BucketItem *)s, from (0 to numitems - 1)
104  *
105  * Each BucketItem is just a key-value pair:
106  *	name -> (char *)
107  *	stuff -> (void *)
108  *
109  * Thus, bucket->list[i]       is the i'th bucket item.
110  *       bucket->list[i].name  is the key (name) of the i'th bucket item
111  *       bucket->list[i].stuff is the value of the i'th bucket item.
112  */
113 
114 static	Bucket	*ctcp_bucket = NULL;
115 
116 /* The name of a CTCP is now the Key of the BucketItem. it used to be in the value */
117 #define CTCP_NAME(i) ctcp_bucket->list[i].name
118 
119 /* The value of a CTCP is the Value of the BucketItem. */
120 #define CTCP(i) ((CtcpEntry *)ctcp_bucket->list[i].stuff)
121 
122 static int	in_ctcp = 0;
123 
124 /*
125  * lookup_ctcp - Convert a CTCP name into a CTCP index.
126  *
127  * Arguments:
128  *	name - the name of a CTCP to be searched for
129  *
130  * Return value:
131  *	-1	- 'name' does not map to an internal CTCP
132  *	>= 0	- 'name' refers to an internal CTCP, an integer 'r'
133  *		  such that CTCP(r) and CTCP_NAME(r) refer to that CTCP
134  */
lookup_ctcp(const char * name)135 static int	lookup_ctcp (const char *name)
136 {
137 	int	i;
138 
139 	for (i = 0; i < ctcp_bucket->numitems; i++)
140 		if (my_stricmp(name, CTCP_NAME(i)) == 0)
141 			return i;
142 
143 	return -1;
144 }
145 
146 
147 /*
148  * To make it easier on myself, I use a macro to ensure ctcp handler C functions
149  * are always prototyped correctly.
150  */
151 #define CTCP_HANDLER(x) \
152 static char * x (const char *from, const char *to, const char *cmd, char *args)
153 
add_ctcp(const char * name,int flag,const char * desc,CTCP_Handler func,CTCP_Handler repl,const char * user_func,const char * user_repl)154 static	void	add_ctcp (const char *name, int flag, const char *desc, CTCP_Handler func, CTCP_Handler repl, const char *user_func, const char *user_repl)
155 {
156 	CtcpEntry *ctcp;
157 	int	numval;
158 	const char *strval;
159 	char *	name_copy;
160 
161 	ctcp = (CtcpEntry *)new_malloc(sizeof(CtcpEntry));
162 	ctcp->flag = flag;
163 	ctcp->desc = malloc_strdup(desc);
164 
165 	ctcp->func = func;
166 	ctcp->repl = repl;
167 
168 	if (user_func)
169 		ctcp->user_func = malloc_strdup(user_func);
170 	else
171 		ctcp->user_func = NULL;
172 	if (user_repl)
173 		ctcp->user_repl = malloc_strdup(user_repl);
174 	else
175 		ctcp->user_repl = NULL;
176 
177 	/* The 'name' belongs to the bucket, so it must be malloc()ed */
178 	name_copy = malloc_strdup(name);
179 	add_to_bucket(ctcp_bucket, name_copy, ctcp);
180 }
181 
182 /*
183  * XXX This global variable is sadly used to tell other systems
184  * about whether a CTCP resulted in an encrypted message.
185  * (SED stands for "Simple Encrypted Data", which used to be the
186  * only form of encryption).  There has not yet been designed
187  * an easier way to pass this kind of info back to the handler
188  * that has to decide whether to throw /on encrypted_privmsg or not.
189  * Oh well.
190  */
191 int     sed = 0;
192 
193 
194 /**************************** CTCP PARSERS ****************************/
195 
196 /********** INLINE EXPANSION CTCPS ***************/
197 /*
198  * do_crypt: Generalized decryption for /CRYPT targets
199  *
200  * Notes:
201  *	This supports encryption over DCC CHAT (`from' will start with "=")
202  *      If the CTCP was sent to a channel, then the peer is the "target".
203  *      If the CTCP was not sent to a channel, then the peer is the sender.
204  *
205  * It will look up to see if you have a /crypt for the peer for the kind of
206  * encryption.  If you do have a /crypt, it will decrypt the message.
207  * If you do not have a /crypt, it will return "[ENCRYPTED MESSAGE]".
208  */
CTCP_HANDLER(do_crypto)209 CTCP_HANDLER(do_crypto)
210 {
211 	Crypt	*key = NULL;
212 	const char	*crypt_who;
213 	char 	*tofrom;
214 	char	*ret = NULL;
215 	char 	*extra = NULL;
216 
217 	if (*from == '=')		/* DCC CHAT message */
218 		crypt_who = from;
219 	else if (is_me(from_server, to))
220 		crypt_who = from;
221 	else
222 		crypt_who = to;
223 
224 	tofrom = malloc_strdup3(to, ",", from);
225 	malloc_strcat2_c(&tofrom, "!", FromUserHost, NULL);
226 
227 	if ((key = is_crypted(tofrom, from_server, cmd)) ||
228 	    (key = is_crypted(crypt_who, from_server, cmd)))
229 		ret = decrypt_msg(args, key);
230 
231 	new_free(&tofrom);
232 
233 	/*
234 	 * Key would be NULL if someone sent us a rogue encrypted
235 	 * message (ie, we don't have a password).  Ret should never
236 	 * be NULL (but we can be defensive against the future).
237 	 * In either case, something went seriously wrong.
238 	 */
239 	if (!key || !ret)
240 	{
241 		if (ret)
242 			new_free(&ret);
243 
244 		sed = 2;
245 		malloc_strcpy(&ret, "[ENCRYPTED MESSAGE]");
246 		return ret;
247 	}
248 
249 
250 	/*
251 	 * NOW WE HANDLE THE DECRYPTED MESSAGE....
252 	 */
253 
254 	/*
255 	 * CTCP messages can be recursive (ie, a decrypted msg
256 	 * might yield another CTCP message), and so we must not
257 	 * recode until we have removed any sub-ctcps!
258 	 */
259 	if (get_server_doing_privmsg(from_server) > 0)
260 		extra = malloc_strdup(do_ctcp(1, from, to, ret));
261 	else if (get_server_doing_notice(from_server) > 0)
262 		extra = malloc_strdup(do_ctcp(0, from, to, ret));
263 	else
264 	{
265 		extra = ret;
266 		ret = NULL;
267 	}
268 
269 	new_free(&ret);
270 	ret = extra;
271 	extra = NULL;
272 
273 	/*
274 	 * What we're left with is just the plain part of the CTCP.
275 	 * In rfc1459_any_to_utf8(), CTCP messages are specifically
276 	 * detected and ignored [because recoding binary data will
277 	 * corrupt the data].  But that does not mean the message
278 	 * doesn't need decoding -- it just needs to be done after
279 	 * the message is decrypted.
280 	 */
281 	inbound_recode(from, from_server, to, ret, &extra);
282 
283 	/*
284 	 * If a recoding actually occurred, free the source string
285 	 * and then use the decoded string going forward.
286 	 */
287 	if (extra)
288 	{
289 		new_free(&ret);
290 		ret = extra;
291 	}
292 
293 	sed = 1;
294 	return ret;
295 }
296 
297 /*
298  * CTCP ACTION - Creates a special "ACTION" level message
299  * 		Does not reply.
300  *		The original CTCP ACTION done by lynX
301  */
CTCP_HANDLER(do_atmosphere)302 CTCP_HANDLER(do_atmosphere)
303 {
304 	int	l;
305 	int	ignore, flood;
306 
307 	if (!args || !*args)
308 		return NULL;
309 
310 	/* Xavier mentioned that we should allow /ignore #chan action */
311 	ignore = check_ignore_channel(from, FromUserHost, to, LEVEL_ACTION);
312 	flood = new_check_flooding(from, FromUserHost,
313 					is_channel(to) ? to : NULL,
314 					args, LEVEL_ACTION);
315 
316 	if (ignore == IGNORED || flood)
317 		return NULL;
318 
319 	if (is_channel(to))
320 	{
321 		l = message_from(to, LEVEL_ACTION);
322 		if (do_hook(ACTION_LIST, "%s %s %s", from, to, args))
323 		{
324 			if (is_current_channel(to, from_server))
325 				put_it("* %s %s", from, args);
326 			else
327 				put_it("* %s:%s %s", from, to, args);
328 		}
329 	}
330 	else
331 	{
332 		l = message_from(from, LEVEL_ACTION);
333 		if (do_hook(ACTION_LIST, "%s %s %s", from, to, args))
334 			put_it("*> %s %s", from, args);
335 	}
336 
337 	pop_message_from(l);
338 	return NULL;
339 }
340 
341 /*
342  * CTCP DCC - Direct Client Connections (file transfers and private chats)
343  *		Does not reply.
344  *		Only user->user CTCP DCCs are acceptable.
345  */
CTCP_HANDLER(do_dcc)346 CTCP_HANDLER(do_dcc)
347 {
348 	char	*type;
349 	char	*description;
350 	char	*inetaddr;
351 	char	*port;
352 	char	*size;
353 	char	*extra_flags;
354 
355 	if (!is_me(from_server, to) && *from != '=')
356 		return NULL;
357 
358 	if     (!(type = next_arg(args, &args)) ||
359 		!(description = (get_int_var(DCC_DEQUOTE_FILENAMES_VAR)
360 				? new_next_arg(args, &args)
361 				: next_arg(args, &args))) ||
362 		!(inetaddr = next_arg(args, &args)) ||
363 		!(port = next_arg(args, &args)))
364 			return NULL;
365 
366 	size = next_arg(args, &args);
367 	extra_flags = next_arg(args, &args);
368 
369 	register_dcc_offer(from, type, description, inetaddr, port, size, extra_flags, args);
370 	return NULL;
371 }
372 
373 /*
374  * If we recieve a CTCP DCC REJECT in a notice, then we want to remove
375  * the offending DCC request
376  */
CTCP_HANDLER(do_dcc_reply)377 CTCP_HANDLER(do_dcc_reply)
378 {
379 	char *subargs = NULL;
380 	char *type = NULL;
381 
382 	if (is_channel(to))
383 		return NULL;
384 
385 	if (args && *args)
386 		subargs = next_arg(args, &args);
387 	if (args && *args)
388 		type = next_arg(args, &args);
389 
390 	if (subargs && type && !strcmp(subargs, "REJECT"))
391 		dcc_reject(from, type, args);
392 
393 	return NULL;
394 }
395 
396 
397 /************************************************************************/
398 /*
399  * split_CTCP - Extract a CTCP out of a message body
400  *
401  * Arguments:
402  *	raw_message -- A message, either a PRIVMSG, NOTICE, or DCC CHAT.
403  *			- If the message contains a CTCP, then the string
404  *			  will be truncated to the part before the CTCP.
405  *			- If the message does not contain a CTCP, it is
406  *			  unchanged.
407  *	ctcp_dest   -- A buffer (of size IRCD_BUFFER_SIZE)
408  *			- If the message contains a CTCP, then the CTCP
409  *			  itself (without the CTCP_DELIMs) will be put
410  *			  in here.
411  *			- If the message does not contain a CTCP, it is
412  *			  unchanged
413  *	after_ctcp  -- A buffer (of size IRCD_BUFFER_SIZE)
414  *			- If the message contains a CTCP, then the part
415  *			  of the message after the CTCP will be put in here
416  *			- If the message does not contain a CTCP, it is
417  *			  unchanged
418  *
419  * Return value:
420  *	-1	- No CTCP was found.  All parameters are unchanged
421  *	 0	- A CTCP was found.  All three parameters were changed
422  */
split_CTCP(char * raw_message,char * ctcp_dest,char * after_ctcp)423 static int split_CTCP (char *raw_message, char *ctcp_dest, char *after_ctcp)
424 {
425 	char 	*ctcp_start,
426 		*ctcp_end;
427 
428 	*ctcp_dest = *after_ctcp = 0;
429 
430 	if (!(ctcp_start = strchr(raw_message, CTCP_DELIM_CHAR)))
431 		return -1;		/* No CTCPs present. */
432 
433 	if (!(ctcp_end = strchr(ctcp_start + 1, CTCP_DELIM_CHAR)))
434 		return -1;		 /* No CTCPs present after all */
435 
436 	*ctcp_start++ = 0;
437 	*ctcp_end++ = 0;
438 
439 	strlcpy(ctcp_dest, ctcp_start, IRCD_BUFFER_SIZE - 1);
440 	strlcpy(after_ctcp, ctcp_end, IRCD_BUFFER_SIZE - 1);
441 	return 0;		/* All done! */
442 }
443 
444 
445 /*
446  * do_ctcp - Remove and process all CTCPs within a message
447  *
448  * Arguments:
449  *	request - Am i processing a request or a response?
450  *		   1 = This is a PRIVMSG or DCC CHAT (a request)
451  *		   0 = This is a NOTICE (a response)
452  *	from	- Who sent the CTCP
453  *	to	- Who received the CTCP (nick, channel, wall)
454  *	str	- The message we received. (may be modified)
455  *		  This must be at least BIG_BUFFER_SIZE+1 or bigger.
456  *
457  * Return value:
458  *	'str' is returned.
459  *	'str' may be modified.
460  *	It is guaranteed that 'str' shall contain no CTCPs upon return.
461  */
do_ctcp(int request,const char * from,const char * to,char * str)462 char *	do_ctcp (int request, const char *from, const char *to, char *str)
463 {
464 	int 	flag;
465 	int	fflag;
466 	char 	local_ctcp_buffer [BIG_BUFFER_SIZE + 1],
467 		the_ctcp          [IRCD_BUFFER_SIZE + 1],
468 		after             [IRCD_BUFFER_SIZE + 1];
469 	char	*ctcp_command,
470 		*ctcp_argument;
471 	char 	*original_ctcp_argument;
472 	int	i;
473 	char	*ptr = NULL;
474 	int	dont_process_more = 0;
475 static	time_t	last_ctcp_parsed = 0;
476 	int	l;
477 	char *	extra = NULL;
478 	int 	delim_char;
479 
480 	/*
481 	 * Messages with less than 2 CTCP delims don't have a CTCP in them.
482 	 * Messages with > 8 delims are probably rogue/attack messages.
483 	 * We can save a lot of cycles by heading those off at the pass.
484 	 */
485 	delim_char = charcount(str, CTCP_DELIM_CHAR);
486 	if (delim_char < 2)
487 		return str;		/* No CTCPs. */
488 	if (delim_char > 8)
489 		dont_process_more = 1;	/* Historical limit of 4 CTCPs */
490 
491 
492 	/*
493 	 * Ignored CTCP messages, or requests during a flood, are
494 	 * removed, but not processed.
495 	 * Although all CTCPs are subject to IGNORE, and requests are subject
496 	 * to flood control; we must apply these restrictions on the inside
497 	 * of the loop, for each CTCP we see.
498 	 */
499 	flag = check_ignore_channel(from, FromUserHost, to, LEVEL_CTCP);
500 	if (request)
501 		fflag = new_check_flooding(from, FromUserHost,
502 						is_channel(to) ? to : NULL,
503 						str, LEVEL_CTCP);
504 	else
505 		fflag = 0;
506 
507 	/* /IGNOREd or flooding messages are removed but not processed */
508 	if (flag == IGNORED || fflag == 1)
509 		dont_process_more = 1;
510 
511 	/* Messages sent to global targets are removed but not processed */
512 	if (*to == '$' || (*to == '#' && !im_on_channel(to, from_server)))
513 		dont_process_more = 1;
514 
515 
516 
517 	/* Set up the window level/logging */
518 	if (im_on_channel(to, from_server))
519 		l = message_from(to, LEVEL_CTCP);
520 	else
521 		l = message_from(from, LEVEL_CTCP);
522 
523 
524 	/* For each CTCP we extract from 'local_ctcp_buffer'.... */
525 	strlcpy(local_ctcp_buffer, str, sizeof(local_ctcp_buffer) - 2);
526 	for (;;new_free(&extra), strlcat(local_ctcp_buffer, after, sizeof(local_ctcp_buffer) - 2))
527 	{
528 		/* Extract next CTCP. If none found, we're done! */
529 		if (split_CTCP(local_ctcp_buffer, the_ctcp, after))
530 			break;		/* All done! */
531 
532 		/* If the CTCP is empty (ie, ^A^A), ignore it.  */
533 		if (!*the_ctcp)
534 			continue;
535 
536 		/* If we're removing-but-not-processing CTCPs, ignore it */
537 		if (dont_process_more)
538 			continue;
539 
540 
541 		/* * * */
542 		/* Seperate the "command" from the "argument" */
543 		ctcp_command = the_ctcp;
544 		if ((ctcp_argument = strchr(the_ctcp, ' ')))
545 			*ctcp_argument++ = 0;
546 		else
547 			ctcp_argument = endstr(the_ctcp);
548 
549 		/*
550 		 * rfc1459_any_to_utf8 specifically ignores CTCPs, because
551 		 * recoding binary data (such as an encrypted message) would
552 		 * corrupt the message.
553 		 *
554 		 * So some CTCPs are "recodable" and some are not.
555 		 *
556 		 * The CTCP_RAW is set for any CTCPs which are NOT
557 		 * to be recoded prior to handling.  These are the encryption
558 		 * CTCPS.
559 		 *
560 		 * For the NORECORD ctcps, we save "original_ctcp_argument"
561 		 * For everybody else, 'ctcp_argument' is recoded.
562 		 */
563 		original_ctcp_argument = ctcp_argument;
564 		inbound_recode(from, from_server, to, ctcp_argument, &extra);
565 		if (extra)
566 			ctcp_argument = extra;
567 
568 		/*
569 		 * Offer it to the user FIRST.
570 		 * CTCPs handled via /on CTCP_REQUEST are treated as
571 		 * ordinary "i sent a reply" CTCPs
572 		 */
573 		if (request)
574 		{
575 			in_ctcp++;
576 
577 			/* If the user "handles" it, then we're done with it! */
578 			if (!do_hook(CTCP_REQUEST_LIST, "%s %s %s %s",
579 					from, to, ctcp_command, ctcp_argument))
580 			{
581 				in_ctcp--;
582 				dont_process_more = 1;
583 				continue;
584 			}
585 
586 			in_ctcp--;
587 			/*
588 			 * User did not "handle" it.  with /on ctcp_request.
589 			 * Let's continue on!
590 			 */
591 		}
592 
593 		/*
594 		 * Next, look for a built-in CTCP handler
595 		 */
596 		/* Does this CTCP have a built-in handler? */
597 		for (i = 0; i < ctcp_bucket->numitems; i++)
598 		{
599 			if (!strcmp(ctcp_command, CTCP_NAME(i)))
600 			{
601 				/* This counts only if there is a function to call! */
602 				if (request && (CTCP(i)->func || CTCP(i)->user_func))
603 					break;
604 				else if (!request && (CTCP(i)->repl || CTCP(i)->user_repl))
605 					break;
606 			}
607 		}
608 
609 		/* There is a function to call. */
610 		if (i < ctcp_bucket->numitems)
611 		{
612 			if ((CTCP(i)->flag & CTCP_RAW))
613 				ctcp_argument = original_ctcp_argument;
614 
615 			in_ctcp++;
616 
617 			/* Call the appropriate callback (four-ways!) */
618 			if (request)
619 			{
620 				if (CTCP(i)->user_func)
621 				{
622 					char *args = NULL;
623 					malloc_sprintf(&args, "%s %s %s %s", from, to, ctcp_command, ctcp_argument);
624 					ptr = call_lambda_function("CTCP", CTCP(i)->user_func, args);
625 					new_free(&args);
626 				}
627 				else if (CTCP(i)->func)
628 					ptr = CTCP(i)->func(from, to, ctcp_command, ctcp_argument);
629 			}
630 			else
631 			{
632 				if (CTCP(i)->user_repl)
633 				{
634 					char *args = NULL;
635 					malloc_sprintf(&args, "%s %s %s %s", from, to, ctcp_command, ctcp_argument);
636 					ptr = call_lambda_function("CTCP", CTCP(i)->user_repl, args);
637 					/* An empty string is the same as NULL here */
638 					if (!ptr || !*ptr)
639 						new_free(&ptr);
640 					new_free(&args);
641 				}
642 				else if (CTCP(i)->repl)
643 					ptr = CTCP(i)->repl(from, to, ctcp_command, ctcp_argument);
644 			}
645 			in_ctcp--;
646 
647 			/***** Was the CTCP "handled"? *****/
648 
649 			/*
650 			 * A CTCP that returns a value is either a
651 			 *  - Argument replacer (CTCP_REPLACE_ARGS)  [CTCP PING]
652 			 *  - Whole-string replacer (default) [CTCP AES256-CBC]
653 			 *
654 			 * Whole-string replacers paste themselves back inline and
655 			 * then go around for another pass.
656 			 *
657 			 * Argument Replacers are still "handled" in the ordinary way.
658 			 */
659 			if (ptr)
660 			{
661 				if (CTCP(i)->flag & CTCP_REPLACE_ARGS)
662 				{
663 					/*
664 					 * "extra" is where we stuck the original ctcp arguments.
665 					 * When a CTCP is handled ordinarily, it will retrieve
666 					 * the CTCP arguments from 'extra'.  So if we are replacing
667 					 * the arguments, it is only logical to put them in 'extra'.
668 					 *
669 					 * This works even if extra == NULL here (because there was
670 					 * no recoding), because we unconditionally reset
671 					 * ctcp_argument to extra below.
672 					 */
673 					malloc_strcpy(&extra, ptr);
674 					new_free(&ptr);
675 				}
676 				else
677 				{
678 					strlcat(local_ctcp_buffer, ptr, sizeof local_ctcp_buffer);
679 					new_free(&ptr);
680 					/* continue; */  /* XXX Sigh */
681 				}
682 			}
683 
684 			/*
685 			 * A CTCP that does not return a value but is "special" (/me, /dcc)
686 			 * is considered "handled"
687 			 */
688 			if (CTCP(i)->flag & CTCP_SPECIAL)
689 				continue;
690 
691 			/* Otherwise, let's continue on! */
692 		}
693 
694 		/* Default handling -- tell the user about it */
695 		/* !!!! Don't remove this, without reading the comments above !!! */
696 		if (extra)
697 			ctcp_argument = extra;
698 		in_ctcp++;
699 		if (request)
700 		{
701 			if (do_hook(CTCP_LIST, "%s %s %s %s", from, to,
702 						ctcp_command, ctcp_argument))
703 			{
704 			    if (is_me(from_server, to))
705 				say("CTCP %s from %s%s%s",
706 					ctcp_command, from,
707 					*ctcp_argument ? ": " : empty_string,
708 					ctcp_argument);
709 			    else
710 				say("CTCP %s from %s to %s%s%s",
711 					ctcp_command, from, to,
712 					*ctcp_argument ? ": " : empty_string,
713 					ctcp_argument);
714 			}
715 		}
716 		else
717 		{
718 			if (do_hook(CTCP_REPLY_LIST, "%s %s %s %s",
719 					from, to, ctcp_command, ctcp_argument))
720 				say("CTCP %s reply from %s: %s",
721 						ctcp_command, from, ctcp_argument);
722 
723 		}
724 		in_ctcp--;
725 
726 		dont_process_more = 1;
727 	}
728 
729 	/*
730 	 * When we are all done, 'local_ctcp_buffer' contains a message without
731 	 * any CTCPs in it!
732 	 *
733 	 * 'str' is required to be BIG_BUFFER_SIZE + 1 or bigger per the API.
734 	 */
735 	pop_message_from(l);
736 	strlcpy(str, local_ctcp_buffer, BIG_BUFFER_SIZE);
737 	return str;
738 }
739 
740 
741 /*
742  * send_ctcp - Format and send a properly encoded CTCP message
743  *
744  * Arguments:
745  *	request  - 1 - This is a CTCP request originating with the user
746  *		   0 - This is a CTCP reply in response to a CTCP request
747  *		   Other values will have undefined behavior.
748  *	to	- The target to send the message to.
749  *	type	- A string describing the CTCP being sent or replied to.
750  *		  Previously this used to be an int into an array of strings,
751  *		  but this is all free-form now.
752  *	format  - NULL -- If the CTCP does not provide any arguments
753  *		  A printf() format -- If the CTCP does provide any arguments
754  *
755  * Notes:
756  *	Because we use send_text(), the following things happen automatically:
757  *	  - We can CTCP any target, including DCC CHATs
758  *	  - All encryption is honored
759  *	We also honor all appropriate /encode-ings
760  *
761  * Example:
762  *	To send a /me to a channel:
763  *		send_ctcp("PRIVMSG", channel, "ACTION", "%s", message);
764  */
send_ctcp(int request,const char * to,const char * type,const char * format,...)765 void	send_ctcp (int request, const char *to, const char *type, const char *format, ...)
766 {
767 	char *	putbuf2;
768 	int	len;
769 	int	l;
770 	const char *protocol;
771 static	time_t	last_ctcp_reply = 0;
772 
773 	/* Make sure that the final \001 doesnt get truncated */
774 	if ((len = IRCD_BUFFER_SIZE - (12 + strlen(to))) <= 0)
775 		return;				/* Whatever. */
776 	putbuf2 = alloca(len);
777 
778 	if (request)
779 		protocol = "PRIVMSG";
780 	else
781 		protocol = "NOTICE";
782 
783 	/*
784 	 * Enforce _outbound_ CTCP Response Flood Protection.
785 	 * To keep botnets from flooding us off by sending
786 	 * us a flurry of CTCP requests from different nicks,
787 	 * we refuse to send a CTCP response until 2 seconds
788 	 * of quiet has happened.
789 	 *
790 	 * This only affects responses.  We never throttle
791 	 * requests.
792 	 */
793 	if (!request && get_int_var(NO_CTCP_FLOOD_VAR))
794 	{
795 		if (time(NULL) - last_ctcp_reply < 2)
796 		{
797                         /*
798                          * This extends the flood protection until
799                          * we dont get a CTCP for 2 seconds.
800                          */
801                         last_ctcp_reply = time(NULL);
802                         if (x_debug & DEBUG_CTCPS)
803                                 say("CTCP flood reply to [%s] dropped", to);
804 			return;
805 		}
806 	}
807 
808 #if 0
809 	if (in_ctcp == 0)
810 		protocol = "PRIVMSG";
811 	else
812 		protocol = "NOTICE";
813 #endif
814 
815 	l = message_from(to, LEVEL_CTCP);
816 	if (format)
817 	{
818 		const char *pb;
819 		char *	extra = NULL;
820 		char 	putbuf [BIG_BUFFER_SIZE + 1];
821 		va_list args;
822 
823 		va_start(args, format);
824 		vsnprintf(putbuf, BIG_BUFFER_SIZE, format, args);
825 		va_end(args);
826 
827 		/*
828 		 * We only recode the ARGUMENTS because the base
829 		 * part of the CTCP is expected to be 7-bit ascii.
830 		 * This isn't strictly enforced, so if you send a
831 		 * CTCP message with a fancy type name, the behavior
832 		 * is unspecified.
833 		 */
834 		pb = outbound_recode(to, from_server, putbuf, &extra);
835 
836 		do_hook(SEND_CTCP_LIST, "%s %s %s %s",
837 				protocol, to, type, pb);
838 		snprintf(putbuf2, len, "%c%s %s%c",
839 				CTCP_DELIM_CHAR, type, pb, CTCP_DELIM_CHAR);
840 
841 		new_free(&extra);
842 	}
843 	else
844 	{
845 		do_hook(SEND_CTCP_LIST, "%s %s %s",
846 				protocol, to, type);
847 		snprintf(putbuf2, len, "%c%s%c",
848 				CTCP_DELIM_CHAR, type, CTCP_DELIM_CHAR);
849 	}
850 
851 	/* XXX - Ugh.  What a hack. */
852 	putbuf2[len - 2] = CTCP_DELIM_CHAR;
853 	putbuf2[len - 1] = 0;
854 
855 	send_text(from_server, to, putbuf2, protocol, 0, 1);
856 	pop_message_from(l);
857 }
858 
859 
860 /*
861  * In a slight departure from tradition, this ctl function is not object-oriented (restful)
862  *
863  *   $ctcpctl(SET <ctcp-name> REQUEST {code})
864  *	Register {code} to be run when client gets a CTCP <ctcp-name> request.
865  *	- If {code} returns a string, that string replaces the CTCP request in
866  *	  the message.  The user is not otherwise notified.
867  *	- If {code} does not return a string, the CTCP is removed normally,
868  *	  and the user is notified of the CTCP request normally
869  *	This creates the new CTCP if necessary.
870  *	Setting a user callback will supercede any internal callback.
871  *
872  *   $ctcpctl(SET <ctcp-name> RESPONSE {code})
873  *	Register {code} to be run when client gets a CTCP <ctcp-name> reply.
874  *	- If {code} returns a string, that string replaces the CTCP request in
875  *	  the message.  The user is not otherwise notified.
876  *	- If {code} does not return a string, the CTCP is removed normally,
877  *	  and the user is notified of the CTCP response normally.
878  *	Setting a user callback will supercede any internal callback.
879  *
880  *   $ctcpctl(SET <ctcp-name> DESCRIPTION <alias_name>)
881  *	Each CTCP has a "description string", which is used by CTCP CLIENTINFO.
882  *
883  *   $ctcpctl(SET <ctcp-name> SPECIAL 1|0)
884  *	A CTCP can be "special", meaning it is entirely self-contained and acts
885  *	as a sink of data.  The two special CTCPs are CTCP ACTION (/me) and
886  *	CTCP DCC (/dcc).  You can make your own special DCCs, but be careful.
887  *
888  *   $ctcpctl(SET <ctcp-name> REPLACE_ARGS 1|0)
889  *      A CTCP handler that returns a value is either a "replacer" or a "rewriter".
890  *      A "Replacer" replaces the arguments to the CTCP (this is what CTCP PING does)
891  *      A "Rewriter" replaces the entire CTCP with a different string (this is
892  *                  what crypto CTCPs do)
893  *      When this is 1, it is a "replacer".  When this is 0, it is a "rewriter".
894  *
895  *   $ctcpctl(SET <ctcp-name> RAW 1|0)
896  *	Ordinarily, everything in the client is a string and has to be subject
897  *	to /encode recoding to make it utf-8 before your ircII code gets to
898  *	interact with it.  Some CTCPs, like the encryption ctcps, work on
899  *	raw/binary data that must not get recoded because it's not a string.
900  *	If RAW is turned on, you will get the raw CTCP-encoded binary
901  *	data, which you _must not_ pass	to /echo unless you like things to
902  *	break.
903  *
904  *   $ctcpctl(GET <ctcp-name> REQUEST)
905  *   $ctcpctl(GET <ctcp-name> RESPONSE)
906  *   $ctcpctl(GET <ctcp-name> DESCRIPTION)
907  *   $ctcpctl(GET <ctcp-name> SPECIAL)
908  *   $ctcpctl(GET <ctcp-name> RAW)
909  *	Fetch information about a built-in CTCP.  If <ctcp-name> does not
910  *	represent an internal CTCP, or the value requested does not apply,
911  * 	(such as a CTCP that does not have a user-defined REQUEST or
912  *	RESPONSE), the empty string is returned.
913  *
914  * Additionally:
915  *
916  *   $ctcpctl(ALL)
917  *	Returns the names of all built-in/registered CTCPs
918  */
BUILT_IN_FUNCTION(function_ctcpctl,input)919 BUILT_IN_FUNCTION(function_ctcpctl, input)
920 {
921 	char *	op;
922 	size_t	op_len;
923 	char *	ctcp_name;
924 	size_t	ctcp_name_len;
925 	char *	field;
926 	size_t	field_len;
927 	int	i;
928 
929 	GET_FUNC_ARG(op, input);
930 	op_len = strlen(op);
931 
932 	if (!my_strnicmp(op, "ALL", op_len)) {
933                 char buffer[BIG_BUFFER_SIZE + 1];
934                 *buffer = '\0';
935 
936                 for (i = 0; i < ctcp_bucket->numitems; i++)
937                 {
938                         const char *name = CTCP_NAME(i);
939                         strlcat(buffer, name, sizeof buffer);
940                         strlcat(buffer, " ", sizeof buffer);
941                 }
942 		RETURN_STR(buffer);
943 	}
944 
945 	GET_FUNC_ARG(ctcp_name, input);
946 	GET_FUNC_ARG(field, input);
947 
948 	upper(ctcp_name);
949 	i = lookup_ctcp(ctcp_name);
950 
951 	if (!my_strnicmp(op, "SET", op_len)) {
952 		/* Boostrap a new built-in CTCP if necessary */
953 		if (i == -1)
954 		{
955 			yell("Added a new CTCP named %s", ctcp_name);
956 			add_ctcp(ctcp_name, CTCP_ORDINARY, ctcp_name, NULL, NULL, NULL, NULL);
957 			i = lookup_ctcp(ctcp_name);
958 		}
959 
960 		if (!my_stricmp(field, "REQUEST")) {
961 			malloc_strcpy(&(CTCP(i)->user_func), input);
962 		} else if (!my_stricmp(field, "RESPONSE")) {
963 			malloc_strcpy(&(CTCP(i)->user_repl), input);
964 		} else if (!my_stricmp(field, "DESCRIPTION")) {
965 			malloc_strcpy(&(CTCP(i)->desc), input);
966 		} else if (!my_stricmp(field, "SPECIAL")) {
967 			if (!strcmp(input, one))
968 				CTCP(i)->flag = (CTCP(i)->flag | CTCP_SPECIAL);
969 			else if (!strcmp(input, zero))
970 				CTCP(i)->flag = (CTCP(i)->flag & ~CTCP_SPECIAL);
971 			else
972 				RETURN_EMPTY;
973 		} else if (!my_stricmp(field, "REPLACE_ARGS")) {
974 			if (!strcmp(input, one))
975 				CTCP(i)->flag = (CTCP(i)->flag | CTCP_REPLACE_ARGS);
976 			else if (!strcmp(input, zero))
977 				CTCP(i)->flag = (CTCP(i)->flag & ~CTCP_REPLACE_ARGS);
978 			else
979 				RETURN_EMPTY;
980 		} else if (!my_stricmp(field, "RAW")) {
981 			if (!strcmp(input, one))
982 				CTCP(i)->flag = (CTCP(i)->flag | CTCP_RAW);
983 			else if (!strcmp(input, zero))
984 				CTCP(i)->flag = (CTCP(i)->flag & ~CTCP_RAW);
985 			else
986 				RETURN_EMPTY;
987 		} else {
988 			RETURN_EMPTY;
989 		}
990 
991 		RETURN_INT(1);
992 	} else if (!my_strnicmp(op, "GET", op_len)) {
993 		if (!my_stricmp(field, "REQUEST")) {
994 			RETURN_STR(CTCP(i)->user_func);
995 		} else if (!my_stricmp(field, "RESPONSE")) {
996 			RETURN_STR(CTCP(i)->user_repl);
997 		} else if (!my_stricmp(field, "DESCRIPTION")) {
998 			RETURN_STR(CTCP(i)->desc);
999 		} else if (!my_stricmp(field, "SPECIAL")) {
1000 			RETURN_INT((CTCP(i)->flag & CTCP_SPECIAL) != 0);
1001 		} else if (!my_stricmp(field, "RAW")) {
1002 			RETURN_INT((CTCP(i)->flag & CTCP_RAW) != 0);
1003 		} else {
1004 			RETURN_EMPTY;
1005 		}
1006 	} else {
1007 		RETURN_EMPTY;
1008 	}
1009 }
1010 
init_ctcp(void)1011 int	init_ctcp (void)
1012 {
1013 	ctcp_bucket = new_bucket();
1014 
1015 	/* Special/Internal CTCPs */
1016 	add_ctcp("ACTION", 		CTCP_SPECIAL,
1017 				"contains action descriptions for atmosphere",
1018 				do_atmosphere, 	do_atmosphere, NULL, NULL);
1019 	add_ctcp("DCC", 		CTCP_SPECIAL,
1020 				"requests a direct_client_connection",
1021 				do_dcc, 	do_dcc_reply, NULL, NULL);
1022 
1023 	/* Strong Crypto CTCPs */
1024 	add_ctcp("AESSHA256-CBC", 	CTCP_ORDINARY | CTCP_RAW,
1025 				"transmit aes256-cbc ciphertext using a sha256 key",
1026 				do_crypto, 	do_crypto, NULL, NULL );
1027 	add_ctcp("AES256-CBC", 		CTCP_ORDINARY | CTCP_RAW,
1028 				"transmit aes256-cbc ciphertext",
1029 				do_crypto, 	do_crypto, NULL, NULL );
1030 	add_ctcp("CAST128ED-CBC", 	CTCP_ORDINARY | CTCP_RAW,
1031 				"transmit cast5-cbc ciphertext",
1032 				do_crypto, 	do_crypto, NULL, NULL );
1033 	add_ctcp("BLOWFISH-CBC", 	CTCP_ORDINARY | CTCP_RAW,
1034 				"transmit blowfish-cbc ciphertext",
1035 				do_crypto, 	do_crypto, NULL, NULL );
1036 	add_ctcp("FISH", 		CTCP_ORDINARY | CTCP_RAW,
1037 				"transmit FiSH (blowfish-ecb with sha256'd key) ciphertext",
1038 				do_crypto, 	do_crypto, NULL, NULL );
1039 	add_ctcp("SED", 		CTCP_ORDINARY | CTCP_RAW,
1040 				"transmit simple_encrypted_data ciphertext",
1041 				do_crypto, 	do_crypto, NULL, NULL );
1042 	add_ctcp("SEDSHA", 		CTCP_ORDINARY | CTCP_RAW,
1043 				"transmit simple_encrypted_data ciphertext using a sha256 key",
1044 				do_crypto, 	do_crypto, NULL, NULL );
1045 
1046 	return 0;
1047 }
1048 
1049 #if 0
1050 void    help_topics_ctcp (FILE *f)
1051 {
1052         int     x;
1053 
1054         for (x = 0; ctcp_cmd[x].name; x++)
1055                 fprintf(f, "ctcp %s\n", ctcp_cmd[x].name);
1056 }
1057 #endif
1058 
1059 
1060