]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_sasl.cpp
2780581902bbc0b81e249c169b827ad2b7f65f68
[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, I_OnUserRegister };
63                 ServerInstance->Modules->Attach(eventlist, this, 2);
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         virtual int OnUserRegister(User *user)
73         {
74                 std::string* str = NULL;
75
76                 if (user->GetExt("sasl"))
77                 {
78                         user->WriteServ("906 %s :SASL authentication aborted", user->nick);
79                         user->Shrink("sasl");
80                 }
81
82                 if (user->GetExt("acountname", str))
83                 {
84                         std::deque<std::string> params;
85                         params.push_back(user->uuid);
86                         params.push_back("accountname");
87                         params.push_back(*str);
88                         Event e((char*)&params, this, "send_metadata");
89                         e.Send(ServerInstance);
90                 }
91                 return 0;
92         }
93
94         virtual ~ModuleSASL()
95         {
96         }
97
98         virtual Version GetVersion()
99         {
100                 return Version(1,2,0,1,VF_VENDOR,API_VERSION);
101         }
102
103         virtual void OnEvent(Event *ev)
104         {
105                 GenericCapHandler(ev, "sasl", "sasl");
106
107                 if (ev->GetEventID() == "encap_received")
108                 {
109                         /* Received encap reply, look for AUTHENTICATE */
110                         std::deque<std::string>* parameters = (std::deque<std::string>*)ev->GetData();
111
112                         User* target = ServerInstance->FindNick((*parameters)[0]);
113
114                         if (target)
115                         {
116                                 /* Found a user */
117                                 parameters->pop_front();
118                                 std::string line = irc::stringjoiner(" ", *parameters, 0, parameters->size() - 1).GetJoined();
119                                 target->WriteServ("AUTHENTICATE %s", line.c_str());
120                         }
121                 }
122                 else if (ev->GetEventID() == "account_login")
123                 {
124                         AccountData* ac = (AccountData*)ev->GetData();
125
126                         if (ac->user->GetExt("sasl"))
127                         {
128                                 ac->user->WriteServ("903 %s :SASL authentication successful", ac->user->nick);
129                                 ac->user->Shrink("sasl");
130                         }
131                 }
132         }
133 };
134
135 MODULE_INIT(ModuleSASL)