]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_sslmodes.cpp
Merge pull request #96 from Justasic/insp20
[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 "ssl.h"
26
27 /* $ModDesc: Provides support for unreal-style channel mode +z */
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                 if (!ServerInstance->Modes->AddMode(&sslm))
87                         throw ModuleException("Could not add new modes!");
88                 Implementation eventlist[] = { I_OnUserPreJoin, I_OnCheckBan, I_On005Numeric };
89                 ServerInstance->Modules->Attach(eventlist, this, 3);
90         }
91
92         ModResult OnUserPreJoin(User* user, Channel* chan, const char* cname, std::string &privs, const std::string &keygiven)
93         {
94                 if(chan && chan->IsModeSet('z'))
95                 {
96                         UserCertificateRequest req(user, this);
97                         req.Send();
98                         if (req.cert)
99                         {
100                                 // Let them in
101                                 return MOD_RES_PASSTHRU;
102                         }
103                         else
104                         {
105                                 // Deny
106                                 user->WriteServ( "489 %s %s :Cannot join channel; SSL users only (+z)", user->nick.c_str(), cname);
107                                 return MOD_RES_DENY;
108                         }
109                 }
110
111                 return MOD_RES_PASSTHRU;
112         }
113
114         ModResult OnCheckBan(User *user, Channel *c, const std::string& mask)
115         {
116                 if (mask[0] == 'z' && mask[1] == ':')
117                 {
118                         UserCertificateRequest req(user, this);
119                         req.Send();
120                         if (req.cert && InspIRCd::Match(req.cert->GetFingerprint(), mask.substr(2)))
121                                 return MOD_RES_DENY;
122                 }
123                 return MOD_RES_PASSTHRU;
124         }
125
126         ~ModuleSSLModes()
127         {
128         }
129
130         void On005Numeric(std::string &output)
131         {
132                 ServerInstance->AddExtBanChar('z');
133         }
134
135         Version GetVersion()
136         {
137                 return Version("Provides support for unreal-style channel mode +z", VF_VENDOR);
138         }
139 };
140
141
142 MODULE_INIT(ModuleSSLModes)
143