]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_jumpserver.cpp
Move and rename typedef LocalUserList to UserManager::LocalList
[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                                 for (UserManager::LocalList::const_iterator i = ServerInstance->Users->local_users.begin(); i != ServerInstance->Users->local_users.end(); ++i)
112                                 {
113                                         LocalUser* t = *i;
114                                         if (!t->IsOper())
115                                         {
116                                                 t->WriteNumeric(RPL_REDIR, "%s %d :Please use this Server/Port instead", parameters[0].c_str(), GetPort(t));
117                                                 ServerInstance->Users->QuitUser(t, reason);
118                                                 n_done++;
119                                         }
120                                 }
121                                 if (n_done)
122                                 {
123                                         n_done_s = ConvToStr(n_done);
124                                 }
125                         }
126
127                         if (redirect_new_users)
128                                 redirect_to = parameters[0];
129
130                         user->WriteNotice("*** Set jumpserver to server '" + parameters[0] + "' port '" + (port ? ConvToStr(port) : "Auto") + ", SSL " + (sslport ? ConvToStr(sslport) : "Auto") + "', flags '+" +
131                                 (redirect_all_immediately ? "a" : "") + (redirect_new_users ? "n'" : "'") +
132                                 (n_done ? " (" + n_done_s + "user(s) redirected): " : ": ") + reason);
133                 }
134
135                 return CMD_SUCCESS;
136         }
137
138         int GetPort(LocalUser* user)
139         {
140                 int p = (SSLClientCert::GetCertificate(&user->eh) ? sslport : port);
141                 if (p == 0)
142                         p = user->GetServerPort();
143                 return p;
144         }
145 };
146
147 class ModuleJumpServer : public Module
148 {
149         CommandJumpserver js;
150  public:
151         ModuleJumpServer() : js(this)
152         {
153         }
154
155         ModResult OnUserRegister(LocalUser* user) CXX11_OVERRIDE
156         {
157                 if (js.redirect_new_users)
158                 {
159                         int port = js.GetPort(user);
160                         user->WriteNumeric(RPL_REDIR, "%s %d :Please use this Server/Port instead",
161                                 js.redirect_to.c_str(), port);
162                         ServerInstance->Users->QuitUser(user, js.reason);
163                         return MOD_RES_PASSTHRU;
164                 }
165                 return MOD_RES_PASSTHRU;
166         }
167
168         void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
169         {
170                 // Emergency way to unlock
171                 if (!status.srcuser)
172                         js.redirect_new_users = false;
173         }
174
175         Version GetVersion() CXX11_OVERRIDE
176         {
177                 return Version("Provides support for the RPL_REDIR numeric and the /JUMPSERVER command.", VF_VENDOR);
178         }
179 };
180
181 MODULE_INIT(ModuleJumpServer)