]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_password_hash.cpp
Merge branch 'insp20' into master.
[user/henk/code/inspircd.git] / src / modules / m_password_hash.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
6  *
7  * This file is part of InspIRCd.  InspIRCd is free software: you can
8  * redistribute it and/or modify it under the terms of the GNU General Public
9  * License as published by the Free Software Foundation, version 2.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20
21 #include "inspircd.h"
22 #include "modules/hash.h"
23
24 /* Handle /MKPASSWD
25  */
26 class CommandMkpasswd : public Command
27 {
28  public:
29         CommandMkpasswd(Module* Creator) : Command(Creator, "MKPASSWD", 2)
30         {
31                 syntax = "<hashtype> <any-text>";
32                 Penalty = 5;
33         }
34
35         CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE
36         {
37                 if (!parameters[0].compare(0, 5, "hmac-", 5))
38                 {
39                         std::string type(parameters[0], 5);
40                         HashProvider* hp = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + type);
41                         if (!hp)
42                         {
43                                 user->WriteNotice("Unknown hash type");
44                                 return CMD_FAILURE;
45                         }
46
47                         if (hp->IsKDF())
48                         {
49                                 user->WriteNotice(type + " does not support HMAC");
50                                 return CMD_FAILURE;
51                         }
52
53                         std::string salt = ServerInstance->GenRandomStr(hp->out_size, false);
54                         std::string target = hp->hmac(salt, parameters[1]);
55                         std::string str = BinToBase64(salt) + "$" + BinToBase64(target, NULL, 0);
56
57                         user->WriteNotice(parameters[0] + " hashed password for " + parameters[1] + " is " + str);
58                         return CMD_SUCCESS;
59                 }
60
61                 HashProvider* hp = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + parameters[0]);
62                 if (!hp)
63                 {
64                         user->WriteNotice("Unknown hash type");
65                         return CMD_FAILURE;
66                 }
67
68                 std::string hexsum = hp->Generate(parameters[1]);
69                 user->WriteNotice(parameters[0] + " hashed password for " + parameters[1] + " is " + hexsum);
70                 return CMD_SUCCESS;
71         }
72 };
73
74 class ModulePasswordHash : public Module
75 {
76  private:
77         CommandMkpasswd cmd;
78
79  public:
80         ModulePasswordHash()
81                 : cmd(this)
82         {
83         }
84
85         ModResult OnPassCompare(Extensible* ex, const std::string &data, const std::string &input, const std::string &hashtype) CXX11_OVERRIDE
86         {
87                 if (!hashtype.compare(0, 5, "hmac-", 5))
88                 {
89                         std::string type(hashtype, 5);
90                         HashProvider* hp = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + type);
91                         if (!hp)
92                                 return MOD_RES_PASSTHRU;
93
94                         if (hp->IsKDF())
95                         {
96                                 ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Tried to use HMAC with %s, which does not support HMAC", type.c_str());
97                                 return MOD_RES_DENY;
98                         }
99
100                         // this is a valid hash, from here on we either accept or deny
101                         std::string::size_type sep = data.find('$');
102                         if (sep == std::string::npos)
103                                 return MOD_RES_DENY;
104                         std::string salt = Base64ToBin(data.substr(0, sep));
105                         std::string target = Base64ToBin(data.substr(sep + 1));
106
107                         if (target == hp->hmac(salt, input))
108                                 return MOD_RES_ALLOW;
109                         else
110                                 return MOD_RES_DENY;
111                 }
112
113                 HashProvider* hp = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + hashtype);
114
115                 /* Is this a valid hash name? */
116                 if (hp)
117                 {
118                         if (hp->Compare(input, data))
119                                 return MOD_RES_ALLOW;
120                         else
121                                 /* No match, and must be hashed, forbid */
122                                 return MOD_RES_DENY;
123                 }
124
125                 // We don't handle this type, let other mods or the core decide
126                 return MOD_RES_PASSTHRU;
127         }
128
129         Version GetVersion() CXX11_OVERRIDE
130         {
131                 return Version("Provides the ability to hash passwords to other modules", VF_VENDOR);
132         }
133 };
134
135 MODULE_INIT(ModulePasswordHash)