]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_sslmodes.cpp
Change match direction of extbans to allow stacking
[user/henk/code/inspircd.git] / src / modules / m_sslmodes.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2009 InspIRCd Development Team
6  * See: http://wiki.inspircd.org/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #include "inspircd.h"
15 #include "transport.h"
16
17 /* $ModDesc: Provides support for unreal-style channel mode +z */
18
19 /** Handle channel mode +z
20  */
21 class SSLMode : public ModeHandler
22 {
23  public:
24         SSLMode(InspIRCd* Instance, Module* Creator) : ModeHandler(Creator, 'z', PARAM_NONE, MODETYPE_CHANNEL) { }
25
26         ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
27         {
28                 if (adding)
29                 {
30                         if (!channel->IsModeSet('z'))
31                         {
32                                 if (IS_LOCAL(source))
33                                 {
34                                         const UserMembList* userlist = channel->GetUsers();
35                                         for(UserMembCIter i = userlist->begin(); i != userlist->end(); i++)
36                                         {
37                                                 BufferedSocketCertificateRequest req(i->first, creator, i->first->GetIOHook());
38                                                 req.Send();
39                                                 if(!req.cert && !ServerInstance->ULine(i->first->server))
40                                                 {
41                                                         source->WriteNumeric(ERR_ALLMUSTSSL, "%s %s :all members of the channel must be connected via SSL", source->nick.c_str(), channel->name.c_str());
42                                                         return MODEACTION_DENY;
43                                                 }
44                                         }
45                                 }
46                                 channel->SetMode('z',true);
47                                 return MODEACTION_ALLOW;
48                         }
49                         else
50                         {
51                                 return MODEACTION_DENY;
52                         }
53                 }
54                 else
55                 {
56                         if (channel->IsModeSet('z'))
57                         {
58                                 channel->SetMode('z',false);
59                                 return MODEACTION_ALLOW;
60                         }
61
62                         return MODEACTION_DENY;
63                 }
64         }
65 };
66
67 class ModuleSSLModes : public Module
68 {
69
70         SSLMode sslm;
71
72  public:
73         ModuleSSLModes(InspIRCd* Me)
74                 : Module(Me), sslm(Me, this)
75         {
76                 if (!ServerInstance->Modes->AddMode(&sslm))
77                         throw ModuleException("Could not add new modes!");
78                 Implementation eventlist[] = { I_OnUserPreJoin, I_OnCheckBan, I_On005Numeric };
79                 ServerInstance->Modules->Attach(eventlist, this, 3);
80         }
81
82         ModResult OnUserPreJoin(User* user, Channel* chan, const char* cname, std::string &privs, const std::string &keygiven)
83         {
84                 if(chan && chan->IsModeSet('z'))
85                 {
86                         BufferedSocketCertificateRequest req(user, this, user->GetIOHook());
87                         req.Send();
88                         if (req.cert)
89                         {
90                                 // Let them in
91                                 return MOD_RES_PASSTHRU;
92                         }
93                         else
94                         {
95                                 // Deny
96                                 user->WriteServ( "489 %s %s :Cannot join channel; SSL users only (+z)", user->nick.c_str(), cname);
97                                 return MOD_RES_DENY;
98                         }
99                 }
100
101                 return MOD_RES_PASSTHRU;
102         }
103
104         ModResult OnCheckBan(User *user, Channel *c, const std::string& mask)
105         {
106                 if (mask[0] == 'z' && mask[1] == ':')
107                 {
108                         BufferedSocketCertificateRequest req(user, this, user->GetIOHook());
109                         req.Send();
110                         if (req.cert && InspIRCd::Match(req.cert->GetFingerprint(), mask.substr(2)))
111                                 return MOD_RES_DENY;
112                 }
113                 return MOD_RES_PASSTHRU;
114         }
115
116         ~ModuleSSLModes()
117         {
118                 ServerInstance->Modes->DelMode(&sslm);
119         }
120
121         void On005Numeric(std::string &output)
122         {
123                 ServerInstance->AddExtBanChar('z');
124         }
125
126         Version GetVersion()
127         {
128                 return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
129         }
130 };
131
132
133 MODULE_INIT(ModuleSSLModes)
134