1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * InspIRCd: (C) 2002-2010 InspIRCd Development Team
6 * See: http://wiki.inspircd.org/Credits
8 * This program is free but copyrighted software; see
9 * the file COPYING for details.
11 * ---------------------------------------------------
18 /* $ModDesc: Allow/Deny connections based upon an arbitary SQL table */
26 class AuthQuery : public SQLQuery
29 const std::string uid;
30 LocalIntExt& pendingExt;
32 AuthQuery(Module* me, const std::string& db, const std::string& q, const std::string& u, LocalIntExt& e, bool v)
33 : SQLQuery(me, db, q), uid(u), pendingExt(e), verbose(v)
35 ServerInstance->Logs->Log("m_sqlauth",DEBUG, "SQLAUTH: db=%s query=\"%s\"", db.c_str(), q.c_str());
38 void OnResult(SQLResult& res)
40 User* user = ServerInstance->FindNick(uid);
45 pendingExt.set(user, AUTH_STATE_NONE);
50 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());
51 pendingExt.set(user, AUTH_STATE_FAIL);
55 void OnError(SQLerror& error)
57 User* user = ServerInstance->FindNick(uid);
60 pendingExt.set(user, AUTH_STATE_FAIL);
62 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());
66 class ModuleSQLAuth : public Module
68 LocalIntExt pendingExt;
69 dynamic_reference<SQLProvider> SQL;
71 std::string freeformquery;
72 std::string killreason;
73 std::string allowpattern;
74 std::string databaseid;
78 ModuleSQLAuth() : pendingExt("sqlauth-wait", this), SQL(this, "SQL")
84 ServerInstance->Modules->AddService(pendingExt);
86 Implementation eventlist[] = { I_OnUserDisconnect, I_OnCheckReady, I_OnRehash, I_OnUserRegister };
87 ServerInstance->Modules->Attach(eventlist, this, 4);
90 void OnRehash(User* user)
94 databaseid = Conf.ReadValue("sqlauth", "dbid", 0); /* Database ID, given to the SQL service provider */
95 freeformquery = Conf.ReadValue("sqlauth", "query", 0); /* Field name where username can be found */
96 killreason = Conf.ReadValue("sqlauth", "killreason", 0); /* Reason to give when access is denied to a user (put your reg details here) */
97 allowpattern = Conf.ReadValue("sqlauth", "allowpattern",0 ); /* Allow nicks matching this pattern without requiring auth */
98 verbose = Conf.ReadFlag("sqlauth", "verbose", 0); /* Set to true if failed connects should be reported to operators */
101 ModResult OnUserRegister(LocalUser* user)
103 // Note this is their initial (unresolved) connect block
104 ConfigTag* tag = user->MyClass->config;
105 if (!tag->getBool("usesqlauth", true))
106 return MOD_RES_PASSTHRU;
108 if (!allowpattern.empty() && InspIRCd::Match(user->nick,allowpattern))
109 return MOD_RES_PASSTHRU;
111 if (pendingExt.get(user))
112 return MOD_RES_PASSTHRU;
114 pendingExt.set(user, AUTH_STATE_BUSY);
116 std::string thisquery = freeformquery;
118 userinfo["nick"] = user->nick;
119 userinfo["pass"] = user->password;
120 userinfo["host"] = user->host;
121 userinfo["ip"] = user->GetIPString();
122 userinfo["gecos"] = user->fullname;
123 userinfo["ident"] = user->ident;
124 userinfo["server"] = user->server;
125 userinfo["uuid"] = user->uuid;
127 HashProvider* md5 = ServerInstance->Modules->FindDataService<HashProvider>("hash/md5");
129 userinfo["md5pass"] = md5->hexsum(user->password);
131 HashProvider* sha256 = ServerInstance->Modules->FindDataService<HashProvider>("hash/sha256");
133 userinfo["sha256pass"] = sha256->hexsum(user->password);
135 SQL->submit(new AuthQuery(this, databaseid, SQL->FormatQuery(freeformquery, userinfo), user->uuid, pendingExt, verbose));
137 return MOD_RES_PASSTHRU;
140 ModResult OnCheckReady(LocalUser* user)
142 switch (pendingExt.get(user))
144 case AUTH_STATE_NONE:
145 return MOD_RES_PASSTHRU;
146 case AUTH_STATE_BUSY:
148 case AUTH_STATE_FAIL:
149 ServerInstance->Users->QuitUser(user, killreason);
152 return MOD_RES_PASSTHRU;
157 return Version("Allow/Deny connections based upon an arbitary SQL table", VF_VENDOR);
161 MODULE_INIT(ModuleSQLAuth)