]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_jumpserver.cpp
e9c07f45fda18816a003a1017d8f3d150a7ff184
[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 /** Handle /JUMPSERVER
26  */
27 class CommandJumpserver : public Command
28 {
29  public:
30         bool redirect_new_users;
31         std::string redirect_to;
32         std::string reason;
33         int port;
34         int sslport;
35
36         CommandJumpserver(Module* Creator) : Command(Creator, "JUMPSERVER", 0, 4)
37         {
38                 flags_needed = 'o';
39                 syntax = "[<server> <port>[:<sslport>] <+/-an> <reason>]";
40                 port = 0;
41                 sslport = 0;
42                 redirect_new_users = false;
43         }
44
45         CmdResult Handle (const std::vector<std::string> &parameters, User *user)
46         {
47                 int n_done = 0;
48                 reason = (parameters.size() < 4) ? "Please use this server/port instead" : parameters[3];
49                 bool redirect_all_immediately = false;
50                 redirect_new_users = true;
51                 bool direction = true;
52                 std::string n_done_s;
53
54                 /* No parameters: jumpserver disabled */
55                 if (!parameters.size())
56                 {
57                         if (port)
58                                 user->WriteNotice("*** Disabled jumpserver (previously set to '" + redirect_to + ":" + ConvToStr(port) + "')");
59                         else
60                                 user->WriteNotice("*** Jumpserver was not enabled.");
61
62                         port = 0;
63                         sslport = 0;
64                         redirect_to.clear();
65                         return CMD_SUCCESS;
66                 }
67
68                 port = 0;
69                 redirect_to.clear();
70
71                 if (parameters.size() >= 3)
72                 {
73                         for (std::string::const_iterator n = parameters[2].begin(); n != parameters[2].end(); ++n)
74                         {
75                                 switch (*n)
76                                 {
77                                         case '+':
78                                                 direction = true;
79                                         break;
80                                         case '-':
81                                                 direction = false;
82                                         break;
83                                         case 'a':
84                                                 redirect_all_immediately = direction;
85                                         break;
86                                         case 'n':
87                                                 redirect_new_users = direction;
88                                         break;
89                                         default:
90                                                 user->WriteNotice("*** Invalid JUMPSERVER flag: " + ConvToStr(*n));
91                                                 return CMD_FAILURE;
92                                         break;
93                                 }
94                         }
95
96                         size_t delimpos = parameters[1].find(':');
97                         port = ConvToInt(parameters[1].substr(0, delimpos ? delimpos : std::string::npos));
98                         sslport = (delimpos == std::string::npos ? 0 : ConvToInt(parameters[1].substr(delimpos + 1)));
99
100                         if (parameters[1].find_first_not_of("0123456789:") != std::string::npos
101                                 || parameters[1].rfind(':') != delimpos
102                                 || port > 65535 || sslport > 65535)
103                         {
104                                 user->WriteNotice("*** Invalid port number");
105                                 return CMD_FAILURE;
106                         }
107
108                         if (redirect_all_immediately)
109                         {
110                                 /* Redirect everyone but the oper sending the command */
111                                 const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers();
112                                 for (UserManager::LocalList::const_iterator i = list.begin(); i != list.end(); )
113                                 {
114                                         // Quitting the user removes it from the list
115                                         LocalUser* t = *i;
116                                         ++i;
117                                         if (!t->IsOper())
118                                         {
119                                                 t->WriteNumeric(RPL_REDIR, "%s %d :Please use this Server/Port instead", parameters[0].c_str(), GetPort(t));
120                                                 ServerInstance->Users->QuitUser(t, reason);
121                                                 n_done++;
122                                         }
123                                 }
124                                 if (n_done)
125                                 {
126                                         n_done_s = ConvToStr(n_done);
127                                 }
128                         }
129
130                         if (redirect_new_users)
131                                 redirect_to = parameters[0];
132
133                         user->WriteNotice("*** Set jumpserver to server '" + parameters[0] + "' port '" + (port ? ConvToStr(port) : "Auto") + ", SSL " + (sslport ? ConvToStr(sslport) : "Auto") + "', flags '+" +
134                                 (redirect_all_immediately ? "a" : "") + (redirect_new_users ? "n'" : "'") +
135                                 (n_done ? " (" + n_done_s + "user(s) redirected): " : ": ") + reason);
136                 }
137
138                 return CMD_SUCCESS;
139         }
140
141         int GetPort(LocalUser* user)
142         {
143                 int p = (SSLClientCert::GetCertificate(&user->eh) ? sslport : port);
144                 if (p == 0)
145                         p = user->GetServerPort();
146                 return p;
147         }
148 };
149
150 class ModuleJumpServer : public Module
151 {
152         CommandJumpserver js;
153  public:
154         ModuleJumpServer() : js(this)
155         {
156         }
157
158         ModResult OnUserRegister(LocalUser* user) CXX11_OVERRIDE
159         {
160                 if (js.redirect_new_users)
161                 {
162                         int port = js.GetPort(user);
163                         user->WriteNumeric(RPL_REDIR, "%s %d :Please use this Server/Port instead",
164                                 js.redirect_to.c_str(), port);
165                         ServerInstance->Users->QuitUser(user, js.reason);
166                         return MOD_RES_PASSTHRU;
167                 }
168                 return MOD_RES_PASSTHRU;
169         }
170
171         void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
172         {
173                 // Emergency way to unlock
174                 if (!status.srcuser)
175                         js.redirect_new_users = false;
176         }
177
178         Version GetVersion() CXX11_OVERRIDE
179         {
180                 return Version("Provides support for the RPL_REDIR numeric and the /JUMPSERVER command.", VF_VENDOR);
181         }
182 };
183
184 MODULE_INIT(ModuleJumpServer)