]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_sslmodes.cpp
Merge pull request #514 from SaberUK/master+virtual-cleanup
[user/henk/code/inspircd.git] / src / modules / m_sslmodes.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
6  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
7  *   Copyright (C) 2006 Craig Edwards <craigedwards@brainbox.cc>
8  *   Copyright (C) 2006 Oliver Lupton <oliverlupton@gmail.com>
9  *
10  * This file is part of InspIRCd.  InspIRCd is free software: you can
11  * redistribute it and/or modify it under the terms of the GNU General Public
12  * License as published by the Free Software Foundation, version 2.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22
23
24 #include "inspircd.h"
25 #include "modules/ssl.h"
26
27 /* $ModDesc: Provides channel mode +z to allow for Secure/SSL only channels */
28
29 /** Handle channel mode +z
30  */
31 class SSLMode : public ModeHandler
32 {
33  public:
34         SSLMode(Module* Creator) : ModeHandler(Creator, "sslonly", 'z', PARAM_NONE, MODETYPE_CHANNEL) { }
35
36         ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
37         {
38                 if (adding)
39                 {
40                         if (!channel->IsModeSet('z'))
41                         {
42                                 if (IS_LOCAL(source))
43                                 {
44                                         const UserMembList* userlist = channel->GetUsers();
45                                         for(UserMembCIter i = userlist->begin(); i != userlist->end(); i++)
46                                         {
47                                                 UserCertificateRequest req(i->first, creator);
48                                                 req.Send();
49                                                 if(!req.cert && !ServerInstance->ULine(i->first->server))
50                                                 {
51                                                         source->WriteNumeric(ERR_ALLMUSTSSL, "%s %s :all members of the channel must be connected via SSL", source->nick.c_str(), channel->name.c_str());
52                                                         return MODEACTION_DENY;
53                                                 }
54                                         }
55                                 }
56                                 channel->SetMode('z',true);
57                                 return MODEACTION_ALLOW;
58                         }
59                         else
60                         {
61                                 return MODEACTION_DENY;
62                         }
63                 }
64                 else
65                 {
66                         if (channel->IsModeSet('z'))
67                         {
68                                 channel->SetMode('z',false);
69                                 return MODEACTION_ALLOW;
70                         }
71
72                         return MODEACTION_DENY;
73                 }
74         }
75 };
76
77 class ModuleSSLModes : public Module
78 {
79
80         SSLMode sslm;
81
82  public:
83         ModuleSSLModes()
84                 : sslm(this)
85         {
86         }
87
88         void init() CXX11_OVERRIDE
89         {
90                 ServerInstance->Modules->AddService(sslm);
91                 Implementation eventlist[] = { I_OnUserPreJoin, I_OnCheckBan, I_On005Numeric };
92                 ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
93         }
94
95         ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven) CXX11_OVERRIDE
96         {
97                 if(chan && chan->IsModeSet('z'))
98                 {
99                         UserCertificateRequest req(user, this);
100                         req.Send();
101                         if (req.cert)
102                         {
103                                 // Let them in
104                                 return MOD_RES_PASSTHRU;
105                         }
106                         else
107                         {
108                                 // Deny
109                                 user->WriteServ( "489 %s %s :Cannot join channel; SSL users only (+z)", user->nick.c_str(), cname.c_str());
110                                 return MOD_RES_DENY;
111                         }
112                 }
113
114                 return MOD_RES_PASSTHRU;
115         }
116
117         ModResult OnCheckBan(User *user, Channel *c, const std::string& mask) CXX11_OVERRIDE
118         {
119                 if ((mask.length() > 2) && (mask[0] == 'z') && (mask[1] == ':'))
120                 {
121                         UserCertificateRequest req(user, this);
122                         req.Send();
123                         if (req.cert && InspIRCd::Match(req.cert->GetFingerprint(), mask.substr(2)))
124                                 return MOD_RES_DENY;
125                 }
126                 return MOD_RES_PASSTHRU;
127         }
128
129         void On005Numeric(std::map<std::string, std::string>& tokens) CXX11_OVERRIDE
130         {
131                 tokens["EXTBAN"].push_back('z');
132         }
133
134         Version GetVersion() CXX11_OVERRIDE
135         {
136                 return Version("Provides channel mode +z to allow for Secure/SSL only channels", VF_VENDOR);
137         }
138 };
139
140 MODULE_INIT(ModuleSSLModes)