2 * InspIRCd -- Internet Relay Chat Daemon
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>
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.
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
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/>.
28 #include "modules/hash.h"
32 class CommandMkpasswd : public Command
35 CommandMkpasswd(Module* Creator) : Command(Creator, "MKPASSWD", 2)
37 syntax = "<hashtype> <plaintext>";
41 CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE
43 if (!parameters[0].compare(0, 5, "hmac-", 5))
45 std::string type(parameters[0], 5);
46 HashProvider* hp = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + type);
49 user->WriteNotice("Unknown hash type");
55 user->WriteNotice(type + " does not support HMAC");
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);
63 user->WriteNotice(parameters[0] + " hashed password for " + parameters[1] + " is " + str);
67 HashProvider* hp = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + parameters[0]);
70 user->WriteNotice("Unknown hash type");
74 std::string hexsum = hp->Generate(parameters[1]);
75 user->WriteNotice(parameters[0] + " hashed password for " + parameters[1] + " is " + hexsum);
80 class ModulePasswordHash : public Module
91 ModResult OnPassCompare(Extensible* ex, const std::string &data, const std::string &input, const std::string &hashtype) CXX11_OVERRIDE
93 if (!hashtype.compare(0, 5, "hmac-", 5))
95 std::string type(hashtype, 5);
96 HashProvider* hp = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + type);
98 return MOD_RES_PASSTHRU;
102 ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Tried to use HMAC with %s, which does not support HMAC", type.c_str());
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)
110 std::string salt = Base64ToBin(data.substr(0, sep));
111 std::string target = Base64ToBin(data.substr(sep + 1));
113 if (target == hp->hmac(salt, input))
114 return MOD_RES_ALLOW;
119 HashProvider* hp = ServerInstance->Modules->FindDataService<HashProvider>("hash/" + hashtype);
121 /* Is this a valid hash name? */
124 if (hp->Compare(input, data))
125 return MOD_RES_ALLOW;
127 /* No match, and must be hashed, forbid */
131 // We don't handle this type, let other mods or the core decide
132 return MOD_RES_PASSTHRU;
135 Version GetVersion() CXX11_OVERRIDE
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);
141 MODULE_INIT(ModulePasswordHash)