]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_sslmodes.cpp
Merge tag 'v2.0.27' into master.
[user/henk/code/inspircd.git] / src / modules / m_sslmodes.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2013 Shawn Smith <shawn@inspircd.org>
5  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
6  *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
7  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
8  *   Copyright (C) 2006 Craig Edwards <craigedwards@brainbox.cc>
9  *   Copyright (C) 2006 Oliver Lupton <oliverlupton@gmail.com>
10  *
11  * This file is part of InspIRCd.  InspIRCd is free software: you can
12  * redistribute it and/or modify it under the terms of the GNU General Public
13  * License as published by the Free Software Foundation, version 2.
14  *
15  * This program is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  */
23
24
25 #include "inspircd.h"
26 #include "modules/ssl.h"
27
28 enum
29 {
30         // From UnrealIRCd.
31         ERR_SECUREONLYCHAN = 489,
32         ERR_ALLMUSTSSL = 490
33 };
34
35 namespace
36 {
37         bool IsSSLUser(UserCertificateAPI& api, User* user)
38         {
39                 if (!api)
40                         return false;
41
42                 ssl_cert* cert = api->GetCertificate(user);
43                 return (cert != NULL);
44         }
45 }
46
47 /** Handle channel mode +z
48  */
49 class SSLMode : public ModeHandler
50 {
51  private:
52         UserCertificateAPI& API;
53
54  public:
55         SSLMode(Module* Creator, UserCertificateAPI& api)
56                 : ModeHandler(Creator, "sslonly", 'z', PARAM_NONE, MODETYPE_CHANNEL)
57                 , API(api)
58         {
59         }
60
61         ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE
62         {
63                 if (adding)
64                 {
65                         if (!channel->IsModeSet(this))
66                         {
67                                 if (IS_LOCAL(source))
68                                 {
69                                         if (!API)
70                                                 return MODEACTION_DENY;
71
72                                         const Channel::MemberMap& userlist = channel->GetUsers();
73                                         for (Channel::MemberMap::const_iterator i = userlist.begin(); i != userlist.end(); ++i)
74                                         {
75                                                 ssl_cert* cert = API->GetCertificate(i->first);
76                                                 if (!cert && !i->first->server->IsULine())
77                                                 {
78                                                         source->WriteNumeric(ERR_ALLMUSTSSL, channel->name, "all members of the channel must be connected via SSL");
79                                                         return MODEACTION_DENY;
80                                                 }
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 (!IsSSLUser(API, 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 : public Module
147 {
148  private:
149         UserCertificateAPI api;
150         SSLMode sslm;
151         SSLModeUser sslquery;
152
153  public:
154         ModuleSSLModes()
155                 : api(this)
156                 , sslm(this, api)
157                 , sslquery(this, api)
158         {
159         }
160
161         ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven) CXX11_OVERRIDE
162         {
163                 if(chan && chan->IsModeSet(sslm))
164                 {
165                         if (!api)
166                                 return MOD_RES_DENY;
167
168                         ssl_cert* cert = api->GetCertificate(user);
169                         if (cert)
170                         {
171                                 // Let them in
172                                 return MOD_RES_PASSTHRU;
173                         }
174                         else
175                         {
176                                 // Deny
177                                 user->WriteNumeric(ERR_SECUREONLYCHAN, cname, "Cannot join channel; SSL users only (+z)");
178                                 return MOD_RES_DENY;
179                         }
180                 }
181
182                 return MOD_RES_PASSTHRU;
183         }
184
185         ModResult OnUserPreMessage(User* user, const MessageTarget& msgtarget, MessageDetails& details) CXX11_OVERRIDE
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 wont 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 (!IsSSLUser(api, user))
200                         {
201                                 /* The sending user is not on an SSL connection */
202                                 user->WriteNumeric(ERR_CANTSENDTOUSER, target->nick, "You are not permitted to send private messages to this user (+z set)");
203                                 return MOD_RES_DENY;
204                         }
205                 }
206                 /* If the user is +z */
207                 else if (user->IsModeSet(sslquery))
208                 {
209                         if (!IsSSLUser(api, target))
210                         {
211                                 user->WriteNumeric(ERR_CANTSENDTOUSER, target->nick, "You must remove usermode 'z' before you are able to send private messages to a non-ssl user.");
212                                 return MOD_RES_DENY;
213                         }
214                 }
215
216                 return MOD_RES_PASSTHRU;
217         }
218
219         ModResult OnCheckBan(User *user, Channel *c, const std::string& mask) CXX11_OVERRIDE
220         {
221                 if ((mask.length() > 2) && (mask[0] == 'z') && (mask[1] == ':'))
222                 {
223                         if (!api)
224                                 return MOD_RES_DENY;
225
226                         ssl_cert* cert = api->GetCertificate(user);
227                         if (cert && InspIRCd::Match(cert->GetFingerprint(), mask.substr(2)))
228                                 return MOD_RES_DENY;
229                 }
230                 return MOD_RES_PASSTHRU;
231         }
232
233         void On005Numeric(std::map<std::string, std::string>& tokens) CXX11_OVERRIDE
234         {
235                 tokens["EXTBAN"].push_back('z');
236         }
237
238         Version GetVersion() CXX11_OVERRIDE
239         {
240                 return Version("Provides user and channel mode +z to allow for SSL-only channels, queries and notices.", VF_VENDOR);
241         }
242 };
243
244 MODULE_INIT(ModuleSSLModes)