]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_jumpserver.cpp
Use !empty() instead of 'size() > 0' when checking parameter count.
[user/henk/code/inspircd.git] / src / modules / m_jumpserver.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2007-2008 Craig Edwards <craigedwards@brainbox.cc>
5  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
6  *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
7  *
8  * This file is part of InspIRCd.  InspIRCd is free software: you can
9  * redistribute it and/or modify it under the terms of the GNU General Public
10  * License as published by the Free Software Foundation, version 2.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21
22 #include "inspircd.h"
23 #include "modules/ssl.h"
24
25 enum
26 {
27         // From ircd-ratbox.
28         RPL_REDIR = 10
29 };
30
31 /** Handle /JUMPSERVER
32  */
33 class CommandJumpserver : public Command
34 {
35  public:
36         bool redirect_new_users;
37         std::string redirect_to;
38         std::string reason;
39         int port;
40         int sslport;
41
42         CommandJumpserver(Module* Creator) : Command(Creator, "JUMPSERVER", 0, 4)
43         {
44                 flags_needed = 'o';
45                 syntax = "[<server> <port>[:<sslport>] <+/-an> <reason>]";
46                 port = 0;
47                 sslport = 0;
48                 redirect_new_users = false;
49         }
50
51         CmdResult Handle(const std::vector<std::string>& parameters, User* user) CXX11_OVERRIDE
52         {
53                 int n_done = 0;
54                 reason = (parameters.size() < 4) ? "Please use this server/port instead" : parameters[3];
55                 bool redirect_all_immediately = false;
56                 redirect_new_users = true;
57                 bool direction = true;
58                 std::string n_done_s;
59
60                 /* No parameters: jumpserver disabled */
61                 if (parameters.empty())
62                 {
63                         if (port)
64                                 user->WriteNotice("*** Disabled jumpserver (previously set to '" + redirect_to + ":" + ConvToStr(port) + "')");
65                         else
66                                 user->WriteNotice("*** Jumpserver was not enabled.");
67
68                         port = 0;
69                         sslport = 0;
70                         redirect_to.clear();
71                         return CMD_SUCCESS;
72                 }
73
74                 port = 0;
75                 redirect_to.clear();
76
77                 if (parameters.size() >= 3)
78                 {
79                         for (std::string::const_iterator n = parameters[2].begin(); n != parameters[2].end(); ++n)
80                         {
81                                 switch (*n)
82                                 {
83                                         case '+':
84                                                 direction = true;
85                                         break;
86                                         case '-':
87                                                 direction = false;
88                                         break;
89                                         case 'a':
90                                                 redirect_all_immediately = direction;
91                                         break;
92                                         case 'n':
93                                                 redirect_new_users = direction;
94                                         break;
95                                         default:
96                                                 user->WriteNotice("*** Invalid JUMPSERVER flag: " + ConvToStr(*n));
97                                                 return CMD_FAILURE;
98                                         break;
99                                 }
100                         }
101
102                         size_t delimpos = parameters[1].find(':');
103                         port = ConvToInt(parameters[1].substr(0, delimpos ? delimpos : std::string::npos));
104                         sslport = (delimpos == std::string::npos ? 0 : ConvToInt(parameters[1].substr(delimpos + 1)));
105
106                         if (parameters[1].find_first_not_of("0123456789:") != std::string::npos
107                                 || parameters[1].rfind(':') != delimpos
108                                 || port > 65535 || sslport > 65535)
109                         {
110                                 user->WriteNotice("*** Invalid port number");
111                                 return CMD_FAILURE;
112                         }
113
114                         if (redirect_all_immediately)
115                         {
116                                 /* Redirect everyone but the oper sending the command */
117                                 const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers();
118                                 for (UserManager::LocalList::const_iterator i = list.begin(); i != list.end(); )
119                                 {
120                                         // Quitting the user removes it from the list
121                                         LocalUser* t = *i;
122                                         ++i;
123                                         if (!t->IsOper())
124                                         {
125                                                 t->WriteNumeric(RPL_REDIR, parameters[0], GetPort(t), "Please use this Server/Port instead");
126                                                 ServerInstance->Users->QuitUser(t, reason);
127                                                 n_done++;
128                                         }
129                                 }
130                                 if (n_done)
131                                 {
132                                         n_done_s = ConvToStr(n_done);
133                                 }
134                         }
135
136                         if (redirect_new_users)
137                                 redirect_to = parameters[0];
138
139                         user->WriteNotice("*** Set jumpserver to server '" + parameters[0] + "' port '" + (port ? ConvToStr(port) : "Auto") + ", SSL " + (sslport ? ConvToStr(sslport) : "Auto") + "', flags '+" +
140                                 (redirect_all_immediately ? "a" : "") + (redirect_new_users ? "n'" : "'") +
141                                 (n_done ? " (" + n_done_s + "user(s) redirected): " : ": ") + reason);
142                 }
143
144                 return CMD_SUCCESS;
145         }
146
147         int GetPort(LocalUser* user)
148         {
149                 int p = (SSLIOHook::IsSSL(&user->eh) ? sslport : port);
150                 if (p == 0)
151                         p = user->GetServerPort();
152                 return p;
153         }
154 };
155
156 class ModuleJumpServer : public Module
157 {
158         CommandJumpserver js;
159  public:
160         ModuleJumpServer() : js(this)
161         {
162         }
163
164         ModResult OnUserRegister(LocalUser* user) CXX11_OVERRIDE
165         {
166                 if (js.redirect_new_users)
167                 {
168                         int port = js.GetPort(user);
169                         user->WriteNumeric(RPL_REDIR, js.redirect_to, port, "Please use this Server/Port instead");
170                         ServerInstance->Users->QuitUser(user, js.reason);
171                         return MOD_RES_DENY;
172                 }
173                 return MOD_RES_PASSTHRU;
174         }
175
176         void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
177         {
178                 // Emergency way to unlock
179                 if (!status.srcuser)
180                         js.redirect_new_users = false;
181         }
182
183         Version GetVersion() CXX11_OVERRIDE
184         {
185                 return Version("Provides support for the RPL_REDIR numeric and the /JUMPSERVER command.", VF_VENDOR);
186         }
187 };
188
189 MODULE_INIT(ModuleJumpServer)