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