]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_starttls.cpp
ea6536ed13585dcd2c601dcbb39b8f6af3cebb82
[user/henk/code/inspircd.git] / src / modules / m_starttls.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2014 Adam <Adam@anope.org>
5  *
6  * This file is part of InspIRCd.  InspIRCd is free software: you can
7  * redistribute it and/or modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation, version 2.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19
20 #include "inspircd.h"
21 #include "modules/ssl.h"
22 #include "modules/cap.h"
23
24 // From IRCv3 tls-3.1
25 enum
26 {
27         RPL_STARTTLS = 670,
28         ERR_STARTTLS = 691
29 };
30
31 class CommandStartTLS : public SplitCommand
32 {
33         dynamic_reference_nocheck<IOHookProvider>& ssl;
34
35  public:
36         CommandStartTLS(Module* mod, dynamic_reference_nocheck<IOHookProvider>& s)
37                 : SplitCommand(mod, "STARTTLS")
38                 , ssl(s)
39         {
40                 works_before_reg = true;
41         }
42
43         CmdResult HandleLocal(LocalUser* user, const Params& parameters) CXX11_OVERRIDE
44         {
45                 if (!ssl)
46                 {
47                         user->WriteNumeric(ERR_STARTTLS, "STARTTLS is not enabled");
48                         return CMD_FAILURE;
49                 }
50
51                 if (user->registered == REG_ALL)
52                 {
53                         user->WriteNumeric(ERR_STARTTLS, "STARTTLS is not permitted after client registration is complete");
54                         return CMD_FAILURE;
55                 }
56
57                 if (user->eh.GetIOHook())
58                 {
59                         user->WriteNumeric(ERR_STARTTLS, "STARTTLS failure");
60                         return CMD_FAILURE;
61                 }
62
63                 user->WriteNumeric(RPL_STARTTLS, "STARTTLS successful, go ahead with TLS handshake");
64                 /* We need to flush the write buffer prior to adding the IOHook,
65                  * otherwise we'll be sending this line inside the SSL session - which
66                  * won't start its handshake until the client gets this line. Currently,
67                  * we assume the write will not block here; this is usually safe, as
68                  * STARTTLS is sent very early on in the registration phase, where the
69                  * user hasn't built up much sendq. Handling a blocked write here would
70                  * be very annoying.
71                  */
72                 user->eh.DoWrite();
73
74                 ssl->OnAccept(&user->eh, NULL, NULL);
75
76                 return CMD_SUCCESS;
77         }
78 };
79
80 class ModuleStartTLS : public Module
81 {
82         CommandStartTLS starttls;
83         Cap::Capability tls;
84         dynamic_reference_nocheck<IOHookProvider> ssl;
85
86  public:
87         ModuleStartTLS()
88                 : starttls(this, ssl)
89                 , tls(this, "tls")
90                 , ssl(this, "ssl")
91         {
92         }
93
94         void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
95         {
96                 ConfigTag* conf = ServerInstance->Config->ConfValue("starttls");
97
98                 std::string newprovider = conf->getString("provider");
99                 if (newprovider.empty())
100                         ssl.SetProvider("ssl");
101                 else
102                         ssl.SetProvider("ssl/" + newprovider);
103         }
104
105         Version GetVersion() CXX11_OVERRIDE
106         {
107                 return Version("Provides support for the STARTTLS command", VF_VENDOR);
108         }
109 };
110
111 MODULE_INIT(ModuleStartTLS)