]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_authcache.cpp
Add authorization cache module
[user/henk/code/inspircd.git] / src / modules / m_authcache.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2010 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 "account.h"
16 #include "ssl.h"
17
18 // Password description - method, authdata
19 typedef std::pair<std::string, std::string> passdesc;
20 typedef std::multimap<std::string,passdesc> AuthMap;
21
22 class ModuleAuthCache : public Module
23 {
24         AuthMap usernames;
25
26  public:
27         ModuleAuthCache()
28         {
29         }
30
31         void init()
32         {
33                 Implementation eventlist[] = { I_OnCheckReady, I_OnDecodeMetaData, I_OnSyncNetwork };
34                 ServerInstance->Modules->Attach(eventlist, this, 3);
35         }
36
37         void OnSyncNetwork(Module* proto, void* opaque)
38         {
39                 for(AuthMap::iterator it = usernames.begin(); it != usernames.end(); it++)
40                         proto->ProtoSendMetaData(opaque, NULL, "authcache", it->second.first +
41                                 " " + it->first + " " + it->second.second);
42         }
43
44         void OnDecodeMetaData(Extensible* dest, const std::string& name, const std::string& value)
45         {
46                 if (dest || name != "authcache")
47                         return;
48                 irc::spacesepstream splitter(value);
49                 std::string method, id, data;
50                 splitter.GetToken(method);
51                 splitter.GetToken(id);
52                 data = splitter.GetRemaining();
53
54                 std::pair<AuthMap::iterator, AuthMap::iterator> it = usernames.equal_range(id);
55                 while (it.first != it.second)
56                 {
57                         if (it.first->second.first == method)
58                         {
59                                 usernames.erase(it.first);
60                                 break;
61                         }
62                         it.first++;
63                 }
64
65                 if (!data.empty())
66                 {
67                         usernames.insert(std::make_pair(id, std::make_pair(method, data)));
68                 }
69         }
70
71         ModResult OnCheckReady(LocalUser* user)
72         {
73                 std::string login;
74
75                 std::pair<AuthMap::iterator, AuthMap::iterator> it = usernames.equal_range(user->nick);
76                 while (it.first != it.second)
77                 {
78                         if (!ServerInstance->PassCompare(user, it.first->second.second, user->password, it.first->second.first))
79                                 login = user->nick;
80                         it.first++;
81                 }
82
83                 SocketCertificateRequest req(&user->eh, this);
84                 req.Send();
85                 if (req.cert)
86                 {
87                         it = usernames.equal_range(req.cert->GetFingerprint());
88                         while (it.first != it.second)
89                         {
90                                 if (it.first->second.first == "sslfp")
91                                         login = it.first->second.second;
92                                 it.first++;
93                         }
94                 }
95
96                 if (!login.empty())
97                 {
98                         AccountExtItem* ext = GetAccountExtItem();
99                         if (ext)
100                         {
101                                 ext->set(user, login);
102                                 AccountEvent(this, user, login).Send();
103                         }
104                 }
105                 return MOD_RES_PASSTHRU;
106         }
107
108         Version GetVersion()
109         {
110                 return Version("Provides an authorization cache for user accounts", VF_OPTCOMMON | VF_VENDOR);
111         }
112 };
113
114 MODULE_INIT(ModuleAuthCache)