]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_password_hash.cpp
44e02eeda8b07368eb15c40ea017d94e476e374c
[user/henk/code/inspircd.git] / src / modules / m_password_hash.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 /* $ModDesc: Allows for hashed oper passwords */
15
16 #include "inspircd.h"
17 #include "hash.h"
18
19 /* Handle /MKPASSWD
20  */
21 class CommandMkpasswd : public Command
22 {
23  public:
24         CommandMkpasswd(Module* Creator) : Command(Creator, "MKPASSWD", 2)
25         {
26                 syntax = "<hashtype> <any-text>";
27                 Penalty = 5;
28         }
29
30         void MakeHash(User* user, const std::string& algo, const std::string& stuff)
31         {
32                 if (algo.substr(0,5) == "hmac-")
33                 {
34                         std::string type = algo.substr(5);
35                         HashProvider* hp = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + type);
36                         if (!hp)
37                         {
38                                 user->WriteServ("NOTICE %s :Unknown hash type", user->nick.c_str());
39                                 return;
40                         }
41                         std::string salt = ServerInstance->GenRandomStr(6, false);
42                         std::string target = hp->hmac(salt, stuff);
43                         std::string str = BinToBase64(salt) + "$" + BinToBase64(target, NULL, 0);
44
45                         user->WriteServ("NOTICE %s :%s hashed password for %s is %s",
46                                 user->nick.c_str(), algo.c_str(), stuff.c_str(), str.c_str());
47                         return;
48                 }
49                 HashProvider* hp = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + algo);
50                 if (hp)
51                 {
52                         /* Now attempt to generate a hash */
53                         user->WriteServ("NOTICE %s :%s hashed password for %s is %s",
54                                 user->nick.c_str(), algo.c_str(), stuff.c_str(), hp->hexsum(stuff).c_str());
55                 }
56                 else
57                 {
58                         user->WriteServ("NOTICE %s :Unknown hash type", user->nick.c_str());
59                 }
60         }
61
62         CmdResult Handle (const std::vector<std::string>& parameters, User *user)
63         {
64                 MakeHash(user, parameters[0], parameters[1]);
65
66                 return CMD_SUCCESS;
67         }
68 };
69
70 class ModuleOperHash : public Module
71 {
72         CommandMkpasswd cmd;
73  public:
74
75         ModuleOperHash() : cmd(this)
76         {
77                 /* Read the config file first */
78                 OnRehash(NULL);
79
80                 ServerInstance->AddCommand(&cmd);
81                 Implementation eventlist[] = { I_OnPassCompare };
82                 ServerInstance->Modules->Attach(eventlist, this, 1);
83         }
84
85         virtual ModResult OnPassCompare(Extensible* ex, const std::string &data, const std::string &input, const std::string &hashtype)
86         {
87                 if (hashtype.substr(0,5) == "hmac-")
88                 {
89                         std::string type = hashtype.substr(5);
90                         HashProvider* hp = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + type);
91                         if (!hp)
92                                 return MOD_RES_PASSTHRU;
93                         // this is a valid hash, from here on we either accept or deny
94                         std::string::size_type sep = data.find('$');
95                         if (sep == std::string::npos)
96                                 return MOD_RES_DENY;
97                         std::string salt = Base64ToBin(data.substr(0, sep));
98                         std::string target = Base64ToBin(data.substr(sep + 1));
99
100                         if (target == hp->hmac(salt, input))
101                                 return MOD_RES_ALLOW;
102                         else
103                                 return MOD_RES_DENY;
104                 }
105
106                 HashProvider* hp = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + hashtype);
107
108                 /* Is this a valid hash name? */
109                 if (hp)
110                 {
111                         /* Compare the hash in the config to the generated hash */
112                         if (data == hp->hexsum(input))
113                                 return MOD_RES_ALLOW;
114                         else
115                                 /* No match, and must be hashed, forbid */
116                                 return MOD_RES_DENY;
117                 }
118
119                 /* Not a hash, fall through to strcmp in core */
120                 return MOD_RES_PASSTHRU;
121         }
122
123         virtual Version GetVersion()
124         {
125                 return Version("Allows for hashed oper passwords",VF_VENDOR);
126         }
127 };
128
129 MODULE_INIT(ModuleOperHash)