]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_sslmodes.cpp
Add user mode +z for ssl-only private messages.
[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 };
33
34 namespace
35 {
36         bool IsSSLUser(UserCertificateAPI& api, User* user)
37         {
38                 if (!api)
39                         return false;
40
41                 ssl_cert* cert = api->GetCertificate(user);
42                 return (cert != NULL);
43         }
44 }
45
46 /** Handle channel mode +z
47  */
48 class SSLMode : public ModeHandler
49 {
50  private:
51         UserCertificateAPI& API;
52
53  public:
54         SSLMode(Module* Creator, UserCertificateAPI& api)
55                 : ModeHandler(Creator, "sslonly", 'z', PARAM_NONE, MODETYPE_CHANNEL)
56                 , API(api)
57         {
58         }
59
60         ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE
61         {
62                 if (adding)
63                 {
64                         if (!channel->IsModeSet(this))
65                         {
66                                 if (IS_LOCAL(source))
67                                 {
68                                         if (!API)
69                                                 return MODEACTION_DENY;
70
71                                         const Channel::MemberMap& userlist = channel->GetUsers();
72                                         for (Channel::MemberMap::const_iterator i = userlist.begin(); i != userlist.end(); ++i)
73                                         {
74                                                 ssl_cert* cert = API->GetCertificate(i->first);
75                                                 if (!cert && !i->first->server->IsULine())
76                                                 {
77                                                         source->WriteNumeric(ERR_ALLMUSTSSL, channel->name, "all members of the channel must be connected via SSL");
78                                                         return MODEACTION_DENY;
79                                                 }
80                                         }
81                                 }
82                                 channel->SetMode(this, true);
83                                 return MODEACTION_ALLOW;
84                         }
85                         else
86                         {
87                                 return MODEACTION_DENY;
88                         }
89                 }
90                 else
91                 {
92                         if (channel->IsModeSet(this))
93                         {
94                                 channel->SetMode(this, false);
95                                 return MODEACTION_ALLOW;
96                         }
97
98                         return MODEACTION_DENY;
99                 }
100         }
101 };
102
103 /** Handle user mode +z
104 */
105 class SSLModeUser : public ModeHandler
106 {
107  private:
108         UserCertificateAPI& API;
109
110  public:
111         SSLModeUser(Module* Creator, UserCertificateAPI& api)
112                 : ModeHandler(Creator, "sslqueries", 'z', PARAM_NONE, MODETYPE_USER)
113                 , API(api)
114         {
115                 if (!ServerInstance->Config->ConfValue("sslmodes")->getBool("enableumode"))
116                         DisableAutoRegister();
117         }
118
119         ModeAction OnModeChange(User* user, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE
120         {
121                 if (adding)
122                 {
123                         if (!dest->IsModeSet(this))
124                         {
125                                 if (!IsSSLUser(API, user))
126                                         return MODEACTION_DENY;
127
128                                 dest->SetMode(this, true);
129                                 return MODEACTION_ALLOW;
130                         }
131                 }
132                 else
133                 {
134                         if (dest->IsModeSet(this))
135                         {
136                                 dest->SetMode(this, false);
137                                 return MODEACTION_ALLOW;
138                         }
139                 }
140
141                 return MODEACTION_DENY;
142         }
143 };
144
145 class ModuleSSLModes : public Module
146 {
147  private:
148         UserCertificateAPI api;
149         SSLMode sslm;
150         SSLModeUser sslquery;
151
152  public:
153         ModuleSSLModes()
154                 : api(this)
155                 , sslm(this, api)
156                 , sslquery(this, api)
157         {
158         }
159
160         ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven) CXX11_OVERRIDE
161         {
162                 if(chan && chan->IsModeSet(sslm))
163                 {
164                         if (!api)
165                                 return MOD_RES_DENY;
166
167                         ssl_cert* cert = api->GetCertificate(user);
168                         if (cert)
169                         {
170                                 // Let them in
171                                 return MOD_RES_PASSTHRU;
172                         }
173                         else
174                         {
175                                 // Deny
176                                 user->WriteNumeric(ERR_SECUREONLYCHAN, cname, "Cannot join channel; SSL users only (+z)");
177                                 return MOD_RES_DENY;
178                         }
179                 }
180
181                 return MOD_RES_PASSTHRU;
182         }
183
184         ModResult OnUserPreMessage(User* user, const MessageTarget& msgtarget, MessageDetails& details) CXX11_OVERRIDE
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 (!IsSSLUser(api, user))
199                         {
200                                 /* The sending user is not on an SSL connection */
201                                 user->WriteNumeric(ERR_CANTSENDTOUSER, target->nick, "You are not permitted to send private messages to this user (+z set)");
202                                 return MOD_RES_DENY;
203                         }
204                 }
205                 /* If the user is +z */
206                 else if (user->IsModeSet(sslquery))
207                 {
208                         if (!IsSSLUser(api, target))
209                         {
210                                 user->WriteNumeric(ERR_CANTSENDTOUSER, target->nick, "You must remove usermode 'z' before you are able to send private messages to a non-ssl user.");
211                                 return MOD_RES_DENY;
212                         }
213                 }
214
215                 return MOD_RES_PASSTHRU;
216         }
217
218         ModResult OnCheckBan(User *user, Channel *c, const std::string& mask) CXX11_OVERRIDE
219         {
220                 if ((mask.length() > 2) && (mask[0] == 'z') && (mask[1] == ':'))
221                 {
222                         if (!api)
223                                 return MOD_RES_DENY;
224
225                         ssl_cert* cert = api->GetCertificate(user);
226                         if (cert && InspIRCd::Match(cert->GetFingerprint(), mask.substr(2)))
227                                 return MOD_RES_DENY;
228                 }
229                 return MOD_RES_PASSTHRU;
230         }
231
232         void On005Numeric(std::map<std::string, std::string>& tokens) CXX11_OVERRIDE
233         {
234                 tokens["EXTBAN"].push_back('z');
235         }
236
237         Version GetVersion() CXX11_OVERRIDE
238         {
239                 return Version("Provides user and channel mode +z to allow for SSL-only channels, queries and notices.", VF_VENDOR);
240         }
241 };
242
243 MODULE_INIT(ModuleSSLModes)