]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_sasl.cpp
Don't send 'sasl successful' numeric on re-identifications after registration
[user/henk/code/inspircd.git] / src / modules / m_sasl.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/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 "m_cap.h"
16 #include "account.h"
17
18 /* $ModDesc: Provides support for atheme SASL via AUTHENTICATE. */
19
20 class CommandAuthenticate : public Command
21 {
22         Module* Creator;
23  public:
24         CommandAuthenticate (InspIRCd* Instance, Module* creator) : Command(Instance,"AUTHENTICATE", 0, 1, true), Creator(creator)
25         {
26                 this->source = "m_sasl.so";
27         }
28
29         CmdResult Handle (const char* const* parameters, int pcnt, User *user)
30         {
31                 if (user->registered != REG_ALL)
32                 {
33                         /* Only act if theyve enabled CAP REQ sasl */
34                         if (user->GetExt("sasl"))
35                         {
36                                 /* Only allow AUTHENTICATE on unregistered clients */
37                                 std::deque<std::string> params;
38                                 params.push_back("*");
39                                 params.push_back("AUTHENTICATE");
40                                 params.push_back(user->uuid);
41
42                                 for (int i = 0; i < pcnt; ++i)
43                                         params.push_back(parameters[i]);
44
45                                 Event e((char*)&params, Creator, "send_encap");
46                                 e.Send(ServerInstance);
47                         }
48                 }
49                 return CMD_FAILURE;
50         }
51 };
52
53
54 class ModuleSASL : public Module
55 {
56         CommandAuthenticate* sasl;
57  public:
58         
59         ModuleSASL(InspIRCd* Me)
60                 : Module(Me)
61         {
62                 Implementation eventlist[] = { I_OnEvent };
63                 ServerInstance->Modules->Attach(eventlist, this, 1);
64
65                 sasl = new CommandAuthenticate(ServerInstance, this);
66                 ServerInstance->AddCommand(sasl);
67
68                 if (!ServerInstance->Modules->Find("m_services_account.so") || !ServerInstance->Modules->Find("m_cap.so"))
69                         ServerInstance->Logs->Log("m_sasl", DEFAULT, "WARNING: m_services_account.so and m_cap.so are not loaded! m_sasl.so will NOT function correctly until these two modules are loaded!");
70         }
71
72
73         virtual ~ModuleSASL()
74         {
75         }
76
77         virtual Version GetVersion()
78         {
79                 return Version(1,2,0,1,VF_VENDOR,API_VERSION);
80         }
81
82         virtual void OnEvent(Event *ev)
83         {
84                 GenericCapHandler(ev, "sasl", "sasl");
85
86                 if (ev->GetEventID() == "encap_received")
87                 {
88                         /* Received encap reply, look for AUTHENTICATE */
89                         std::deque<std::string>* parameters = (std::deque<std::string>*)ev->GetData();
90
91                         User* target = ServerInstance->FindNick((*parameters)[0]);
92
93                         if (target)
94                         {
95                                 /* Found a user */
96                                 parameters->pop_front();
97                                 std::string line = irc::stringjoiner(" ", *parameters, 0, parameters->size() - 1).GetJoined();
98                                 target->WriteServ("AUTHENTICATE %s", line.c_str());
99                         }
100                 }
101                 else if (ev->GetEventID() == "account_login")
102                 {
103                         AccountData* ac = (AccountData*)ev->GetData();
104
105                         if (ac->user->GetExt("sasl"))
106                         {
107                                 ac->user->WriteServ("903 %s :SASL authentication successful", ac->user->nick);
108                                 ac->user->Shrink("sasl");
109                         }
110                 }
111         }
112 };
113
114 MODULE_INIT(ModuleSASL)