]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_sslmodes.cpp
bc5cb56752314693c108ad697e0f9500454d2403
[user/henk/code/inspircd.git] / src / modules / m_sslmodes.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2020 Matt Schatz <genius3000@g3k.solutions>
5  *   Copyright (C) 2013, 2017-2020 Sadie Powell <sadie@witchery.services>
6  *   Copyright (C) 2013 Shawn Smith <ShawnSmith0828@gmail.com>
7  *   Copyright (C) 2012-2014 Attila Molnar <attilamolnar@hush.com>
8  *   Copyright (C) 2012 Robby <robby@chatbelgie.be>
9  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
10  *   Copyright (C) 2009 Uli Schlachter <psychon@inspircd.org>
11  *   Copyright (C) 2008 Robin Burchell <robin+git@viroteck.net>
12  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
13  *   Copyright (C) 2006-2007, 2010 Craig Edwards <brain@inspircd.org>
14  *
15  * This file is part of InspIRCd.  InspIRCd is free software: you can
16  * redistribute it and/or modify it under the terms of the GNU General Public
17  * License as published by the Free Software Foundation, version 2.
18  *
19  * This program is distributed in the hope that it will be useful, but WITHOUT
20  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
22  * details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
26  */
27
28
29 #include "inspircd.h"
30 #include "modules/ctctags.h"
31 #include "modules/ssl.h"
32
33 enum
34 {
35         // From UnrealIRCd.
36         ERR_SECUREONLYCHAN = 489,
37         ERR_ALLMUSTSSL = 490
38 };
39
40 /** Handle channel mode +z
41  */
42 class SSLMode : public ModeHandler
43 {
44  private:
45         UserCertificateAPI& API;
46
47  public:
48         SSLMode(Module* Creator, UserCertificateAPI& api)
49                 : ModeHandler(Creator, "sslonly", 'z', PARAM_NONE, MODETYPE_CHANNEL)
50                 , API(api)
51         {
52         }
53
54         ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE
55         {
56                 if (adding)
57                 {
58                         if (!channel->IsModeSet(this))
59                         {
60                                 if (IS_LOCAL(source))
61                                 {
62                                         if (!API)
63                                         {
64                                                 source->WriteNumeric(ERR_ALLMUSTSSL, channel->name, "Unable to determine whether all members of the channel are connected via TLS (SSL)");
65                                                 return MODEACTION_DENY;
66                                         }
67
68                                         unsigned long nonssl = 0;
69                                         const Channel::MemberMap& userlist = channel->GetUsers();
70                                         for (Channel::MemberMap::const_iterator i = userlist.begin(); i != userlist.end(); ++i)
71                                         {
72                                                 ssl_cert* cert = API->GetCertificate(i->first);
73                                                 if (!cert && !i->first->server->IsULine())
74                                                         nonssl++;
75                                         }
76
77                                         if (nonssl)
78                                         {
79                                                 source->WriteNumeric(ERR_ALLMUSTSSL, channel->name, InspIRCd::Format("All members of the channel must be connected via TLS (SSL) (%lu/%lu are non-TLS (SSL))",
80                                                         nonssl, static_cast<unsigned long>(userlist.size())));
81                                                 return MODEACTION_DENY;
82                                         }
83                                 }
84                                 channel->SetMode(this, true);
85                                 return MODEACTION_ALLOW;
86                         }
87                         else
88                         {
89                                 return MODEACTION_DENY;
90                         }
91                 }
92                 else
93                 {
94                         if (channel->IsModeSet(this))
95                         {
96                                 channel->SetMode(this, false);
97                                 return MODEACTION_ALLOW;
98                         }
99
100                         return MODEACTION_DENY;
101                 }
102         }
103 };
104
105 /** Handle user mode +z
106 */
107 class SSLModeUser : public ModeHandler
108 {
109  private:
110         UserCertificateAPI& API;
111
112  public:
113         SSLModeUser(Module* Creator, UserCertificateAPI& api)
114                 : ModeHandler(Creator, "sslqueries", 'z', PARAM_NONE, MODETYPE_USER)
115                 , API(api)
116         {
117                 if (!ServerInstance->Config->ConfValue("sslmodes")->getBool("enableumode"))
118                         DisableAutoRegister();
119         }
120
121         ModeAction OnModeChange(User* user, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE
122         {
123                 if (adding)
124                 {
125                         if (!dest->IsModeSet(this))
126                         {
127                                 if (!API || !API->GetCertificate(user))
128                                         return MODEACTION_DENY;
129
130                                 dest->SetMode(this, true);
131                                 return MODEACTION_ALLOW;
132                         }
133                 }
134                 else
135                 {
136                         if (dest->IsModeSet(this))
137                         {
138                                 dest->SetMode(this, false);
139                                 return MODEACTION_ALLOW;
140                         }
141                 }
142
143                 return MODEACTION_DENY;
144         }
145 };
146
147 class ModuleSSLModes
148         : public Module
149         , public CTCTags::EventListener
150 {
151  private:
152         UserCertificateAPI api;
153         SSLMode sslm;
154         SSLModeUser sslquery;
155
156  public:
157         ModuleSSLModes()
158                 : CTCTags::EventListener(this)
159                 , api(this)
160                 , sslm(this, api)
161                 , sslquery(this, api)
162         {
163         }
164
165         ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven) CXX11_OVERRIDE
166         {
167                 if(chan && chan->IsModeSet(sslm))
168                 {
169                         if (!api)
170                         {
171                                 user->WriteNumeric(ERR_SECUREONLYCHAN, cname, "Cannot join channel; unable to determine if you are a TLS (SSL) user (+z is set)");
172                                 return MOD_RES_DENY;
173                         }
174
175                         if (!api->GetCertificate(user))
176                         {
177                                 user->WriteNumeric(ERR_SECUREONLYCHAN, cname, "Cannot join channel; TLS (SSL) users only (+z is set)");
178                                 return MOD_RES_DENY;
179                         }
180                 }
181
182                 return MOD_RES_PASSTHRU;
183         }
184
185         ModResult HandleMessage(User* user, const MessageTarget& msgtarget)
186         {
187                 if (msgtarget.type != MessageTarget::TYPE_USER)
188                         return MOD_RES_PASSTHRU;
189
190                 User* target = msgtarget.Get<User>();
191
192                 /* If one or more of the parties involved is a ulined service, we won't stop it. */
193                 if (user->server->IsULine() || target->server->IsULine())
194                         return MOD_RES_PASSTHRU;
195
196                 /* If the target is +z */
197                 if (target->IsModeSet(sslquery))
198                 {
199                         if (!api || !api->GetCertificate(user))
200                         {
201                                 /* The sending user is not on an SSL connection */
202                                 user->WriteNumeric(Numerics::CannotSendTo(target, "messages", &sslquery));
203                                 return MOD_RES_DENY;
204                         }
205                 }
206                 /* If the user is +z */
207                 else if (user->IsModeSet(sslquery))
208                 {
209                         if (!api || !api->GetCertificate(target))
210                         {
211                                 user->WriteNumeric(Numerics::CannotSendTo(target, "messages", &sslquery, true));
212                                 return MOD_RES_DENY;
213                         }
214                 }
215
216                 return MOD_RES_PASSTHRU;
217         }
218
219         ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details) CXX11_OVERRIDE
220         {
221                 return HandleMessage(user, target);
222         }
223
224         ModResult OnUserPreTagMessage(User* user, const MessageTarget& target, CTCTags::TagMessageDetails& details) CXX11_OVERRIDE
225         {
226                 return HandleMessage(user, target);
227         }
228
229         ModResult OnCheckBan(User *user, Channel *c, const std::string& mask) CXX11_OVERRIDE
230         {
231                 if ((mask.length() > 2) && (mask[0] == 'z') && (mask[1] == ':'))
232                 {
233                         const std::string fp = api ? api->GetFingerprint(user) : "";
234                         if (!fp.empty() && InspIRCd::Match(fp, mask.substr(2)))
235                                 return MOD_RES_DENY;
236                 }
237                 return MOD_RES_PASSTHRU;
238         }
239
240         void On005Numeric(std::map<std::string, std::string>& tokens) CXX11_OVERRIDE
241         {
242                 tokens["EXTBAN"].push_back('z');
243         }
244
245         Version GetVersion() CXX11_OVERRIDE
246         {
247                 return Version("Adds channel mode z (sslonly) which prevents users who are not connecting using TLS (SSL) from joining the channel and user mode z (sslqueries) to prevent messages from non-TLS (SSL) users.", VF_VENDOR);
248         }
249 };
250
251 MODULE_INIT(ModuleSSLModes)