unrealircd

- supernets unrealircd source & configuration
git clone git://git.acid.vegas/unrealircd.git
Log | Files | Refs | Archive | README | LICENSE

knock.c (3970B)

      1 /*
      2  *   IRC - Internet Relay Chat, src/modules/knock.c
      3  *   (C) 2004 The UnrealIRCd Team
      4  *
      5  *   See file AUTHORS in IRC package for additional names of
      6  *   the programmers.
      7  *
      8  *   This program is free software; you can redistribute it and/or modify
      9  *   it under the terms of the GNU General Public License as published by
     10  *   the Free Software Foundation; either version 1, or (at your option)
     11  *   any later version.
     12  *
     13  *   This program is distributed in the hope that it will be useful,
     14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  *   GNU General Public License for more details.
     17  *
     18  *   You should have received a copy of the GNU General Public License
     19  *   along with this program; if not, write to the Free Software
     20  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     21  */
     22 
     23 #include "unrealircd.h"
     24 
     25 CMD_FUNC(cmd_knock);
     26 
     27 #define MSG_KNOCK 	"KNOCK"	
     28 
     29 ModuleHeader MOD_HEADER
     30   = {
     31 	"knock",
     32 	"5.0",
     33 	"command /knock", 
     34 	"UnrealIRCd Team",
     35 	"unrealircd-6",
     36     };
     37 
     38 MOD_INIT()
     39 {
     40 	CommandAdd(modinfo->handle, MSG_KNOCK, cmd_knock, 2, CMD_USER);
     41 	ISupportAdd(modinfo->handle, "KNOCK", NULL);
     42 	MARK_AS_OFFICIAL_MODULE(modinfo);
     43 	return MOD_SUCCESS;
     44 }
     45 
     46 MOD_LOAD()
     47 {
     48 	return MOD_SUCCESS;
     49 }
     50 
     51 MOD_UNLOAD()
     52 {
     53 	return MOD_SUCCESS;
     54 }
     55 
     56 /*
     57 ** cmd_knock
     58 **	parv[1] - channel
     59 **	parv[2] - reason
     60 **
     61 ** Coded by Stskeeps
     62 ** Additional bugfixes/ideas by codemastr
     63 ** (C) codemastr & Stskeeps
     64 ** 
     65 ** 2019-11-27: Behavior change. We now send the KNOCK
     66 ** across servers and only deliver the channel notice
     67 ** to local channel members. The reason for this is that
     68 ** otherwise we cannot count KNOCKs network-wide which
     69 ** caused knock-floods per-channel to be per-server
     70 ** rather than global, which undesirable.
     71 ** Unfortunately, this means that if you have a mixed
     72 ** U4 and U5 network you will see KNOCK notices twice
     73 ** for every attempt.
     74 */
     75 CMD_FUNC(cmd_knock)
     76 {
     77 	Channel *channel;
     78 	Hook *h;
     79 	int i = 0;
     80 	MessageTag *mtags = NULL;
     81 	const char *reason;
     82 
     83 	if (IsServer(client))
     84 		return;
     85 
     86 	if (parc < 2 || *parv[1] == '\0')
     87 	{
     88 		sendnumeric(client, ERR_NEEDMOREPARAMS, "KNOCK");
     89 		return;
     90 	}
     91 
     92 	reason = parv[2] ? parv[2] : "no reason specified";
     93 
     94 	if (MyConnect(client) && !valid_channelname(parv[1]))
     95 	{
     96 		sendnumeric(client, ERR_NOSUCHCHANNEL, parv[1]);
     97 		return;
     98 	}
     99 
    100 	if (!(channel = find_channel(parv[1])))
    101 	{
    102 		sendnumeric(client, ERR_CANNOTKNOCK, parv[1], "Channel does not exist!");
    103 		return;
    104 	}
    105 
    106 	/* IsMember bugfix by codemastr */
    107 	if (IsMember(client, channel) == 1)
    108 	{
    109 		sendnumeric(client, ERR_CANNOTKNOCK, channel->name, "You're already there!");
    110 		return;
    111 	}
    112 
    113 	if (!has_channel_mode(channel, 'i'))
    114 	{
    115 		sendnumeric(client, ERR_CANNOTKNOCK, channel->name, "Channel is not invite only!");
    116 		return;
    117 	}
    118 
    119 	if (is_banned(client, channel, BANCHK_JOIN, NULL, NULL))
    120 	{
    121 		sendnumeric(client, ERR_CANNOTKNOCK, channel->name, "You're banned!");
    122 		return;
    123 	}
    124 
    125 	for (h = Hooks[HOOKTYPE_PRE_KNOCK]; h; h = h->next)
    126 	{
    127 		i = (*(h->func.intfunc))(client, channel, &reason);
    128 		if (i == HOOK_DENY || i == HOOK_ALLOW)
    129 			break;
    130 	}
    131 
    132 	if (i == HOOK_DENY)
    133 		return;
    134 
    135 	if (MyUser(client) &&
    136 	    !ValidatePermissionsForPath("immune:knock-flood",client,NULL,NULL,NULL) &&
    137 	    flood_limit_exceeded(client, FLD_KNOCK))
    138 	{
    139 		sendnumeric(client, ERR_CANNOTKNOCK, parv[1], "You are KNOCK flooding");
    140 		return;
    141 	}
    142 
    143 	new_message(&me, NULL, &mtags);
    144 
    145 	sendto_channel(channel, &me, NULL, "o",
    146 	               0, SEND_LOCAL, mtags,
    147 	               ":%s NOTICE @%s :[Knock] by %s!%s@%s (%s)",
    148 	               me.name, channel->name,
    149 	               client->name, client->user->username, GetHost(client),
    150 	               reason);
    151 
    152 	sendto_server(client, 0, 0, mtags, ":%s KNOCK %s :%s", client->id, channel->name, reason);
    153 
    154 	if (MyUser(client))
    155 		sendnotice(client, "Knocked on %s", channel->name);
    156 
    157         RunHook(HOOKTYPE_KNOCK, client, channel, mtags, parv[2]);
    158 
    159 	free_message_tags(mtags);
    160 }