2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
6 * This file is part of InspIRCd. InspIRCd is free software: you can
7 * redistribute it and/or modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation, version 2.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 /* $ModDesc: Allow/Deny connections based upon an arbitrary SQL table */
32 class AuthQuery : public SQLQuery
35 const std::string uid;
36 LocalIntExt& pendingExt;
38 AuthQuery(Module* me, const std::string& u, LocalIntExt& e, bool v)
39 : SQLQuery(me), uid(u), pendingExt(e), verbose(v)
43 void OnResult(SQLResult& res)
45 User* user = ServerInstance->FindNick(uid);
50 pendingExt.set(user, AUTH_STATE_NONE);
55 ServerInstance->SNO->WriteGlobalSno('a', "Forbidden connection from %s!%s@%s (SQL query returned no matches)", user->nick.c_str(), user->ident.c_str(), user->host.c_str());
56 pendingExt.set(user, AUTH_STATE_FAIL);
60 void OnError(SQLerror& error)
62 User* user = ServerInstance->FindNick(uid);
65 pendingExt.set(user, AUTH_STATE_FAIL);
67 ServerInstance->SNO->WriteGlobalSno('a', "Forbidden connection from %s!%s@%s (SQL query failed: %s)", user->nick.c_str(), user->ident.c_str(), user->host.c_str(), error.Str());
71 class ModuleSQLAuth : public Module
73 LocalIntExt pendingExt;
74 dynamic_reference<SQLProvider> SQL;
76 std::string freeformquery;
77 std::string killreason;
78 std::string allowpattern;
82 ModuleSQLAuth() : pendingExt("sqlauth-wait", this), SQL(this, "SQL")
88 ServerInstance->Modules->AddService(pendingExt);
90 Implementation eventlist[] = { I_OnUserDisconnect, I_OnCheckReady, I_OnRehash, I_OnUserRegister };
91 ServerInstance->Modules->Attach(eventlist, this, 4);
94 void OnRehash(User* user)
96 ConfigTag* conf = ServerInstance->Config->ConfValue("sqlauth");
97 std::string dbid = conf->getString("dbid");
99 SQL.SetProvider("SQL");
101 SQL.SetProvider("SQL/" + dbid);
102 freeformquery = conf->getString("query");
103 killreason = conf->getString("killreason");
104 allowpattern = conf->getString("allowpattern");
105 verbose = conf->getBool("verbose");
108 ModResult OnUserRegister(LocalUser* user)
110 // Note this is their initial (unresolved) connect block
111 ConfigTag* tag = user->MyClass->config;
112 if (!tag->getBool("usesqlauth", true))
113 return MOD_RES_PASSTHRU;
115 if (!allowpattern.empty() && InspIRCd::Match(user->nick,allowpattern))
116 return MOD_RES_PASSTHRU;
118 if (pendingExt.get(user))
119 return MOD_RES_PASSTHRU;
123 ServerInstance->SNO->WriteGlobalSno('a', "Forbiding connection from %s!%s@%s (SQL database not present)",
124 user->nick.c_str(), user->ident.c_str(), user->host.c_str());
125 ServerInstance->Users->QuitUser(user, killreason);
126 return MOD_RES_PASSTHRU;
129 pendingExt.set(user, AUTH_STATE_BUSY);
132 SQL->PopulateUserInfo(user, userinfo);
133 userinfo["pass"] = user->password;
135 HashProvider* md5 = ServerInstance->Modules->FindDataService<HashProvider>("hash/md5");
137 userinfo["md5pass"] = md5->hexsum(user->password);
139 HashProvider* sha256 = ServerInstance->Modules->FindDataService<HashProvider>("hash/sha256");
141 userinfo["sha256pass"] = sha256->hexsum(user->password);
143 SQL->submit(new AuthQuery(this, user->uuid, pendingExt, verbose), freeformquery, userinfo);
145 return MOD_RES_PASSTHRU;
148 ModResult OnCheckReady(LocalUser* user)
150 switch (pendingExt.get(user))
152 case AUTH_STATE_NONE:
153 return MOD_RES_PASSTHRU;
154 case AUTH_STATE_BUSY:
156 case AUTH_STATE_FAIL:
157 ServerInstance->Users->QuitUser(user, killreason);
160 return MOD_RES_PASSTHRU;
165 return Version("Allow/Deny connections based upon an arbitrary SQL table", VF_VENDOR);
169 MODULE_INIT(ModuleSQLAuth)