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