1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2018 Sadie Powell <sadie@witchery.services>
5  *   Copyright (C) 2013-2015 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 #pragma once
22 
23 #include "utils.h"
24 #include "treeserver.h"
25 
26 class ProtocolException : public ModuleException
27 {
28  public:
ProtocolException(const std::string & msg)29 	ProtocolException(const std::string& msg)
30 		: ModuleException("Protocol violation: " + msg)
31 	{
32 	}
33 };
34 
35 /** Base class for server-to-server commands that may have a (remote) user source or server source.
36  */
37 class ServerCommand : public CommandBase
38 {
39  public:
40 	ServerCommand(Module* Creator, const std::string& Name, unsigned int MinPara = 0, unsigned int MaxPara = 0);
41 
42 	/** Register this object in the ServerCommandManager
43 	 */
44 	void RegisterService() CXX11_OVERRIDE;
45 
46 	virtual CmdResult Handle(User* user, Params& parameters) = 0;
47 	RouteDescriptor GetRouting(User* user, const Params& parameters) CXX11_OVERRIDE;
48 
49 	/**
50 	 * Extract the TS from a string.
51 	 * @param tsstr The string containing the TS.
52 	 * @return The raw timestamp value.
53 	 * This function throws a ProtocolException if it considers the TS invalid. Note that the detection of
54 	 * invalid timestamps is not designed to be bulletproof, only some cases - like "0" - trigger an exception.
55 	 */
56 	static time_t ExtractTS(const std::string& tsstr);
57 };
58 
59 /** Base class for server-to-server command handlers which are only valid if their source is a user.
60  * When a server sends a command of this type and the source is a server (sid), the link is aborted.
61  */
62 template <class T>
63 class UserOnlyServerCommand : public ServerCommand
64 {
65  public:
66 	UserOnlyServerCommand(Module* Creator, const std::string& Name, unsigned int MinPara = 0, unsigned int MaxPara = 0)
ServerCommand(Creator,Name,MinPara,MaxPara)67 		: ServerCommand(Creator, Name, MinPara, MaxPara) { }
68 
Handle(User * user,Params & parameters)69 	CmdResult Handle(User* user, Params& parameters) CXX11_OVERRIDE
70 	{
71 		RemoteUser* remoteuser = IS_REMOTE(user);
72 		if (!remoteuser)
73 			throw ProtocolException("Invalid source");
74 		return static_cast<T*>(this)->HandleRemote(remoteuser, parameters);
75 	}
76 };
77 
78 /** Base class for server-to-server command handlers which are only valid if their source is a server.
79  * When a server sends a command of this type and the source is a user (uuid), the link is aborted.
80  */
81 template <class T>
82 class ServerOnlyServerCommand : public ServerCommand
83 {
84  public:
85 	ServerOnlyServerCommand(Module* Creator, const std::string& Name, unsigned int MinPara = 0, unsigned int MaxPara = 0)
ServerCommand(Creator,Name,MinPara,MaxPara)86 		: ServerCommand(Creator, Name, MinPara, MaxPara) { }
87 
Handle(User * user,CommandBase::Params & parameters)88 	CmdResult Handle(User* user, CommandBase::Params& parameters) CXX11_OVERRIDE
89 	{
90 		if (!IS_SERVER(user))
91 			throw ProtocolException("Invalid source");
92 		TreeServer* server = TreeServer::Get(user);
93 		return static_cast<T*>(this)->HandleServer(server, parameters);
94 	}
95 };
96 
97 class ServerCommandManager
98 {
99 	typedef TR1NS::unordered_map<std::string, ServerCommand*> ServerCommandMap;
100 	ServerCommandMap commands;
101 
102  public:
103 	ServerCommand* GetHandler(const std::string& command) const;
104 	bool AddCommand(ServerCommand* cmd);
105 };
106