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