]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/coremods/core_user/core_user.cpp
Fix sending malformed pong messages in some cases.
[user/henk/code/inspircd.git] / src / coremods / core_user / core_user.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2017-2020 Sadie Powell <sadie@witchery.services>
5  *   Copyright (C) 2014-2016, 2018 Attila Molnar <attilamolnar@hush.com>
6  *
7  * This file is part of InspIRCd.  InspIRCd is free software: you can
8  * redistribute it and/or modify it under the terms of the GNU General Public
9  * License as published by the Free Software Foundation, version 2.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20
21 #include "inspircd.h"
22 #include "core_user.h"
23
24 /** Handle /PASS.
25  */
26 class CommandPass : public SplitCommand
27 {
28  public:
29         /** Constructor for pass.
30          */
31         CommandPass(Module* parent)
32                 : SplitCommand(parent, "PASS", 1, 1)
33         {
34                 works_before_reg = true;
35                 Penalty = 0;
36                 syntax = "<password>";
37         }
38
39         /** Handle command.
40          * @param parameters The parameters to the command
41          * @param user The user issuing the command
42          * @return A value from CmdResult to indicate command success or failure.
43          */
44         CmdResult HandleLocal(LocalUser* user, const Params& parameters) CXX11_OVERRIDE
45         {
46                 // Check to make sure they haven't registered -- Fix by FCS
47                 if (user->registered == REG_ALL)
48                 {
49                         user->CommandFloodPenalty += 1000;
50                         user->WriteNumeric(ERR_ALREADYREGISTERED, "You may not reregister");
51                         return CMD_FAILURE;
52                 }
53                 user->password = parameters[0];
54
55                 return CMD_SUCCESS;
56         }
57 };
58
59 /** Handle /PING.
60  */
61 class CommandPing : public SplitCommand
62 {
63  public:
64         /** Constructor for ping.
65          */
66         CommandPing(Module* parent)
67                 : SplitCommand(parent, "PING", 1)
68         {
69                 syntax = "<cookie> [<servername>]";
70         }
71
72         /** Handle command.
73          * @param parameters The parameters to the command
74          * @param user The user issuing the command
75          * @return A value from CmdResult to indicate command success or failure.
76          */
77         CmdResult HandleLocal(LocalUser* user, const Params& parameters) CXX11_OVERRIDE
78         {
79                 size_t origin = parameters.size() > 1 ? 1 : 0;
80                 if (parameters[origin].empty())
81                 {
82                         user->WriteNumeric(ERR_NOORIGIN, "No origin specified");
83                         return CMD_FAILURE;
84                 }
85
86                 ClientProtocol::Messages::Pong pong(parameters[0], origin ? parameters[1] : ServerInstance->Config->GetServerName());
87                 user->Send(ServerInstance->GetRFCEvents().pong, pong);
88                 return CMD_SUCCESS;
89         }
90 };
91
92 /** Handle /PONG.
93  */
94 class CommandPong : public Command
95 {
96  public:
97         /** Constructor for pong.
98          */
99         CommandPong(Module* parent)
100                 : Command(parent, "PONG", 1)
101         {
102                 Penalty = 0;
103                 syntax = "<cookie> [<servername>]";
104         }
105
106         /** Handle command.
107          * @param parameters The parameters to the command
108          * @param user The user issuing the command
109          * @return A value from CmdResult to indicate command success or failure.
110          */
111         CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE
112         {
113                 size_t origin = parameters.size() > 1 ? 1 : 0;
114                 if (parameters[origin].empty())
115                 {
116                         user->WriteNumeric(ERR_NOORIGIN, "No origin specified");
117                         return CMD_FAILURE;
118                 }
119
120                 // set the user as alive so they survive to next ping
121                 LocalUser* localuser = IS_LOCAL(user);
122                 if (localuser)
123                 {
124                         // Increase penalty unless we've sent a PING and this is the reply
125                         if (localuser->lastping)
126                                 localuser->CommandFloodPenalty += 1000;
127                         else
128                                 localuser->lastping = 1;
129                 }
130                 return CMD_SUCCESS;
131         }
132 };
133
134 void MessageWrapper::Wrap(const std::string& message, std::string& out)
135 {
136         // If there is a fixed message, it is stored in prefix. Otherwise prefix contains
137         // only the prefix, so append the message and the suffix
138         out.assign(prefix);
139         if (!fixed)
140                 out.append(message).append(suffix);
141 }
142
143 void MessageWrapper::ReadConfig(const char* prefixname, const char* suffixname, const char* fixedname)
144 {
145         ConfigTag* tag = ServerInstance->Config->ConfValue("options");
146         prefix = tag->getString(fixedname);
147         fixed = (!prefix.empty());
148         if (!fixed)
149         {
150                 prefix = tag->getString(prefixname);
151                 suffix = tag->getString(suffixname);
152         }
153 }
154
155 class CoreModUser : public Module
156 {
157         CommandAway cmdaway;
158         CommandNick cmdnick;
159         CommandPart cmdpart;
160         CommandPass cmdpass;
161         CommandPing cmdping;
162         CommandPong cmdpong;
163         CommandQuit cmdquit;
164         CommandUser cmduser;
165         CommandIson cmdison;
166         CommandUserhost cmduserhost;
167         SimpleUserModeHandler invisiblemode;
168         ModeUserOperator operatormode;
169         ModeUserServerNoticeMask snomaskmode;
170
171  public:
172         CoreModUser()
173                 : cmdaway(this)
174                 , cmdnick(this)
175                 , cmdpart(this)
176                 , cmdpass(this)
177                 , cmdping(this)
178                 , cmdpong(this)
179                 , cmdquit(this)
180                 , cmduser(this)
181                 , cmdison(this)
182                 , cmduserhost(this)
183                 , invisiblemode(this, "invisible", 'i')
184                 , operatormode(this)
185                 , snomaskmode(this)
186         {
187         }
188
189         void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
190         {
191                 cmdpart.msgwrap.ReadConfig("prefixpart", "suffixpart", "fixedpart");
192                 cmdquit.msgwrap.ReadConfig("prefixquit", "suffixquit", "fixedquit");
193         }
194
195         Version GetVersion() CXX11_OVERRIDE
196         {
197                 return Version("Provides the AWAY, ISON, NICK, PART, PASS, PING, PONG, QUIT, USERHOST, and USER commands", VF_VENDOR|VF_CORE);
198         }
199 };
200
201 MODULE_INIT(CoreModUser)