]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/extra/m_sqlauth.cpp
Changed description comment
[user/henk/code/inspircd.git] / src / modules / extra / m_sqlauth.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  Inspire is copyright (C) 2002-2004 ChatSpike-Dev.
6  *                       E-mail:
7  *                <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *     
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *            the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 #include <stdio.h>
18 #include <string>
19 #include <stdlib.h>
20 #include <time.h>
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <sys/time.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <poll.h>
29 #include "users.h"
30 #include "channels.h"
31 #include "modules.h"
32 #include "inspircd.h"
33 #include "m_sql.h"
34
35 /* $ModDesc: An SQL test module */
36
37 Server *Srv;
38
39 class ModuleSQLAuth : public Module
40 {
41         ConfigReader* Conf;
42         std::string usertable;
43         std::string userfield;
44         std::string passfield;
45         std::string encryption;
46         std::string killreason;
47         unsigned long dbid;
48         Module* SQLModule;
49
50  public:
51         bool ReadConfig()
52         {
53                 Conf = new ConfigReader();
54                 usertable = Conf->ReadValue("sqlauth","usertable",0);   // user table name
55                 dbid = Conf->ReadInteger("sqlauth","dbid",0,true);      // database id of a database configured in m_sql (see m_sql config)
56                 userfield = Conf->ReadValue("sqlauth","userfield",0);   // field name where username can be found
57                 passfield = Conf->ReadValue("sqlauth","passfield",0);   // field name where password can be found
58                 killreason = Conf->ReadValue("sqlauth","killreason",0); // reason to give when access is denied to a user (put your reg details here)
59                 encryption = Conf->ReadValue("sqlauth","encryption",0); // name of sql function used to encrypt password, e.g. "md5" or "passwd".
60                                                                         // define, but leave blank if no encryption is to be used.
61                 delete Conf;
62                 SQLModule = Srv->FindModule("m_sql.so");
63                 if (!SQLModule)
64                         Srv->Log(DEFAULT,"WARNING: m_sqlauth.so could not initialize because m_sql.so is not loaded. Load the module and rehash your server.");
65                 return (SQLModule);
66         }
67
68         ModuleSQLAuth()
69         {
70                 Srv = new Server;
71                 ReadConfig();
72         }
73
74         virtual void OnRehash()
75         {
76                 ReadConfig();
77         }
78
79         virtual void OnUserRegister(userrec* user)
80         {
81                 if (!CheckCredentials(user->nick,user->password))
82                 {
83                         Srv->QuitUser(user,killreason);
84                 }
85         }
86
87         bool CheckCredentials(std::string username, std::string password)
88         {
89                 bool found = false;
90
91                 // is the sql module loaded? If not, we don't attempt to do anything.
92                 if (!SQLModule)
93                         return false;
94
95                 // Create a request containing the SQL query and send it to m_sql.so
96                 SQLRequest* query = new SQLRequest(SQL_RESULT,1,"SELECT * FROM "+usertable+" WHERE "+userfield+"='"+username+"' AND "+passfield+"="+encmethod+"('"+password+"')");
97                 Request queryrequest((char*)query, this, SQLModule);
98                 SQLResult* result = (SQLResult*)queryrequest.Send();
99
100                 // Did we get "OK" as a result?
101                 if (result->GetType() == SQL_OK)
102                 {
103
104                         // if we did, this means we may now request a row... there should be only one row for each user, so,
105                         // we don't need to loop to fetch multiple rows.
106                         SQLRequest* rowrequest = new SQLRequest(SQL_ROW,1,"");
107                         Request rowquery((char*)rowrequest, this, SQLModule);
108                         SQLResult* rowresult = (SQLResult*)rowquery.Send();
109
110                         // did we get a row? If we did, we can now do something with the fields
111                         if (rowresult->GetType() == SQL_ROW)
112                         {
113                                 if (rowrequest->GetField(userfield) == username)
114                                 {
115                                         // because the query directly asked for the password hash, we do not need to check it -
116                                         // if it didnt match it wont be returned in the first place from the SELECT.
117                                         // This just checks we didnt get an empty row by accident.
118                                         found = true;
119                                 }
120                                 delete rowresult;
121                         }
122                         else
123                         {
124                                 // we didn't have a row.
125                                 found = false;
126                         }
127                         delete rowrequest;
128                         delete result;
129                 }
130                 else
131                 {
132                         // the query was bad
133                         found = false;
134                 }
135                 query->SetQueryType(SQL_DONE);
136                 query->SetConnID(1);
137                 Request donerequest((char*)query, this, SQLModule);
138                 donerequest.Send();
139                 delete query;
140                 return found;
141         }
142
143         virtual ~ModuleSQLAuth()
144         {
145                 delete Srv;
146         }
147         
148         virtual Version GetVersion()
149         {
150                 return Version(1,0,0,1,VF_VENDOR);
151         }
152         
153 };
154
155 class ModuleSQLAuthFactory : public ModuleFactory
156 {
157  public:
158         ModuleSQLAuthFactory()
159         {
160         }
161         
162         ~ModuleSQLAuthFactory()
163         {
164         }
165         
166         virtual Module * CreateModule()
167         {
168                 return new ModuleSQLAuth;
169         }
170         
171 };
172
173
174 extern "C" void * init_module( void )
175 {
176         return new ModuleSQLAuthFactory;
177 }
178