]> jfr.im git - irc/unrealircd/unrealircd-webpanel.git/blame - plugins/sql_auth/sql_auth.php
missing a word
[irc/unrealircd/unrealircd-webpanel.git] / plugins / sql_auth / sql_auth.php
CommitLineData
ea27475b
VP
1<?php
2
3require_once "SQL/sql.php";
ce9cf366 4require_once "SQL/settings.php";
4d634d0a 5
ea27475b
VP
6class sql_auth
7{
b44a2e97 8 public $name = "SQLAuth";
ea27475b
VP
9 public $author = "Valware";
10 public $version = "1.0";
11 public $description = "Provides a User Auth and Management Panel with an SQL backend";
b65f0496 12 public $email = "v.a.pond@outlook.com";
ea27475b
VP
13
14 function __construct()
15 {
5015c85c 16 self::create_tables();
b44a2e97 17 Hook::func(HOOKTYPE_PRE_HEADER, 'sql_auth::session_start');
33f512fa 18 Hook::func(HOOKTYPE_FOOTER, 'sql_auth::add_footer_info');
6930484c
VP
19 Hook::func(HOOKTYPE_USER_LOOKUP, 'sql_auth::get_user');
20 Hook::func(HOOKTYPE_USERMETA_ADD, 'sql_auth::add_usermeta');
21 Hook::func(HOOKTYPE_USERMETA_DEL, 'sql_auth::del_usermeta');
22 Hook::func(HOOKTYPE_USERMETA_GET, 'sql_auth::get_usermeta');
180b8ec1
VP
23 Hook::func(HOOKTYPE_USER_CREATE, 'sql_auth::user_create');
24 Hook::func(HOOKTYPE_GET_USER_LIST, 'sql_auth::get_user_list');
25 Hook::func(HOOKTYPE_USER_DELETE, 'sql_auth::user_delete');
5a7f0cde 26 Hook::func(HOOKTYPE_EDIT_USER, 'sql_auth::edit_core');
b6a7129b 27 Hook::func(HOOKTYPE_PRE_OVERVIEW_CARD, 'sql_auth::add_pre_overview_card');
4d634d0a
VP
28
29 if (defined('SQL_DEFAULT_USER')) // we've got a default account
30 {
6930484c 31 $lkup = new PanelUser(SQL_DEFAULT_USER['username']);
4d634d0a
VP
32
33 if (!$lkup->id) // doesn't exist, add it with full privileges
34 {
180b8ec1
VP
35 $user = [];
36 $user['user_name'] = SQL_DEFAULT_USER['username'];
37 $user['user_pass'] = SQL_DEFAULT_USER['password'];
38 $user['err'] = "";
39 create_new_user($user);
4d634d0a 40 }
79d2194c
VP
41 $lkup = new PanelUser(SQL_DEFAULT_USER['username']);
42 if (!user_can($lkup, PERMISSION_MANAGE_USERS))
43 $lkup->add_permission(PERMISSION_MANAGE_USERS);
4d634d0a 44 }
ea27475b
VP
45 }
46
ea27475b 47
33f512fa
VP
48 public static function add_footer_info($empty)
49 {
94890799 50 if (!($user = unreal_get_current_user()))
33f512fa
VP
51 return;
52
53 else {
54 echo "<code>Admin Panel v" . WEBPANEL_VERSION . "</code>";
55 }
56 }
57
b6a7129b
BM
58 public static function add_pre_overview_card($empty)
59 {
60 if (defined('SQL_DEFAULT_USER'))
61 Message::Fail("Warning: SQL_DEFAULT_USER is set in config.php. You should remove that item now, as it is only used during installation.");
62 }
63
3a8ffab8 64 /* pre-Header hook */
b44a2e97
VP
65 public static function session_start($n)
66 {
06369f59
VP
67 if (!isset($_SESSION))
68 {
69 session_set_cookie_params(3600);
70 session_start();
71 }
454379e3 72 if (!isset($_SESSION['id']) || empty($_SESSION))
b44a2e97 73 {
bc75e1cb 74 $current_page = $_SERVER['REQUEST_URI'];
ce9cf366
VP
75 $tok = split($_SERVER['SCRIPT_FILENAME'], "/");
76 if ($check = security_check() && $tok[count($tok) - 1] !== "error.php") {
77 header("Location: " . BASE_URL . "plugins/sql_auth/error.php");
78 die();
79 }
bc75e1cb 80 header("Location: ".BASE_URL."login/?redirect=".urlencode($current_page));
454379e3 81 die();
b44a2e97 82 }
08ce3aa7
VP
83 else
84 {
94890799 85 if (!unreal_get_current_user()) // user no longer exists
08ce3aa7
VP
86 {
87 session_destroy();
321b7b81 88 header("Location: ".BASE_URL."login");
f5e3ecee 89 die();
08ce3aa7 90 }
e3e93dde 91 // you'll be automatically logged out after one hour of inactivity
08ce3aa7 92 }
b44a2e97 93 }
ea27475b 94
ce9cf366
VP
95 /**
96 * Create the tables we'll be using in the SQLdb
97 * @return void
98 */
5015c85c
VP
99 public static function create_tables()
100 {
101 $conn = sqlnew();
102 $conn->query("CREATE TABLE IF NOT EXISTS " . SQL_PREFIX . "users (
103 user_id int AUTO_INCREMENT NOT NULL,
104 user_name VARCHAR(255) NOT NULL,
105 user_pass VARCHAR(255) NOT NULL,
9a674833 106 user_email VARCHAR(255),
5015c85c
VP
107 user_fname VARCHAR(255),
108 user_lname VARCHAR(255),
109 user_bio VARCHAR(255),
110 created VARCHAR(255),
111 PRIMARY KEY (user_id)
112 )");
9a674833
VP
113
114 /**
115 * Patch for beta users
116 * This adds the email column to existing tables without it
117 */
118 $columns = $conn->query("SHOW COLUMNS FROM " . SQL_PREFIX . "users");
119 $column_names = array();
120 $c = $columns->fetchAll();
f5173b9c 121
9a674833
VP
122 foreach($c as $column) {
123 $column_names[] = $column['Field'];
124 }
125 $column_exists = in_array("user_email", $column_names);
126 if (!$column_exists) {
127 $conn->query("ALTER TABLE " . SQL_PREFIX . "users ADD COLUMN user_email varchar(255)");
128 }
129
f5173b9c
VP
130 /**
131 * Another patch for beta users
132 * This changes the size of the meta_value so we can store more
133 */
50023a80 134
5015c85c
VP
135 $conn->query("CREATE TABLE IF NOT EXISTS " . SQL_PREFIX . "user_meta (
136 meta_id int AUTO_INCREMENT NOT NULL,
137 user_id int NOT NULL,
138 meta_key VARCHAR(255) NOT NULL,
139 meta_value VARCHAR(255),
140 PRIMARY KEY (meta_id)
141 )");
ce9cf366
VP
142 $conn->query("CREATE TABLE IF NOT EXISTS " . SQL_PREFIX . "auth_settings (
143 id int AUTO_INCREMENT NOT NULL,
144 setting_key VARCHAR(255) NOT NULL,
145 setting_value VARCHAR(255),
146 PRIMARY KEY (id)
147 )");
33f512fa
VP
148 $conn->query("CREATE TABLE IF NOT EXISTS " . SQL_PREFIX . "fail2ban (
149 id int AUTO_INCREMENT NOT NULL,
150 ip VARCHAR(255) NOT NULL,
151 count VARCHAR(255),
152 PRIMARY KEY (id)
153 )");
50023a80
VP
154 $c = [];
155 if (($columns = $conn->query("SHOW COLUMNS FROM ".SQL_PREFIX."user_meta")));
156 $c = $columns->fetchAll();
157 if (!empty($c))
158 $conn->query("ALTER TABLE `".SQL_PREFIX."user_meta` CHANGE `meta_value` `meta_value` VARCHAR(5000) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL");
159
160
9c643401 161 new AuthSettings();
5015c85c
VP
162 }
163
6930484c
VP
164 /* We convert $u with a full user as an object ;D*/
165 public static function get_user(&$u)
166 {
167 $id = $u['id'];
168 $name = $u['name'];
169 $conn = sqlnew();
170
171 if ($id)
172 {
173 $prep = $conn->prepare("SELECT * FROM " . SQL_PREFIX . "users WHERE user_id = :id LIMIT 1");
174 $prep->execute(["id" => strtolower($id)]);
175 }
176 elseif ($name)
177 {
178 $prep = $conn->prepare("SELECT * FROM " . SQL_PREFIX . "users WHERE LOWER(user_name) = :name LIMIT 1");
179 $prep->execute(["name" => strtolower($name)]);
180 }
181 $data = NULL;
182 $obj = (object) [];
183 if ($prep)
184 $data = $prep->fetchAll();
185 if (isset($data[0]) && $data = $data[0])
186 {
187 $obj->id = $data['user_id'];
188 $obj->username = $data['user_name'];
189 $obj->passhash = $data['user_pass'];
190 $obj->first_name = $data['user_fname'] ?? NULL;
191 $obj->last_name = $data['user_lname'] ?? NULL;
192 $obj->created = $data['created'];
193 $obj->bio = $data['user_bio'];
9a674833 194 $obj->email = $data['user_email'];
6930484c
VP
195 $obj->user_meta = (new PanelUser_Meta($obj->id))->list;
196 }
197 $u['object'] = $obj;
198 }
199
200 public static function get_usermeta(&$u)
201 {
6930484c
VP
202 $list = &$u['meta'];
203 $id = $u['id'];
204 $conn = sqlnew();
205 if (isset($id))
206 {
207 $prep = $conn->prepare("SELECT * FROM " . SQL_PREFIX . "user_meta WHERE user_id = :id");
208 $prep->execute(["id" => $id]);
209 }
210 foreach ($prep->fetchAll() as $row)
211 {
212 $list[$row['meta_key']] = $row['meta_value'];
213 }
214 }
215
216 public static function add_usermeta(&$meta)
217 {
da6fa2d1 218 $meta = $meta['meta'];
6930484c
VP
219 $conn = sqlnew();
220 /* check if it exists first, update it if it does */
221 $query = "SELECT * FROM " . SQL_PREFIX . "user_meta WHERE user_id = :id AND meta_key = :key";
222 $stmt = $conn->prepare($query);
223 $stmt->execute(["id" => $meta['id'], "key" => $meta['key']]);
224 if ($stmt->rowCount()) // it exists, update instead of insert
225 {
226 $query = "UPDATE " . SQL_PREFIX . "user_meta SET meta_value = :value WHERE user_id = :id AND meta_key = :key";
227 $stmt = $conn->prepare($query);
228 $stmt->execute($meta);
229 if ($stmt->rowCount())
230 return true;
231 return false;
232 }
233
234 else
235 {
236 $query = "INSERT INTO " . SQL_PREFIX . "user_meta (user_id, meta_key, meta_value) VALUES (:id, :key, :value)";
237 $stmt = $conn->prepare($query);
238 $stmt->execute($meta);
239 if ($stmt->rowCount())
240 return true;
241 return false;
242 }
243 }
244 public static function del_usermeta(&$u)
245 {
246 $conn = sqlnew();
247 $query = "DELETE FROM " . SQL_PREFIX . "user_meta WHERE user_id = :id AND meta_key = :key";
248 $stmt = $conn->prepare($query);
249 $stmt->execute($u['meta']);
250 if ($stmt->rowCount())
251 return true;
252 return false;
253 }
180b8ec1
VP
254 public static function user_create(&$u)
255 {
256 $username = $u['user_name'];
9f9d16d5
VP
257 $first_name = $u['fname'] ?? NULL;
258 $last_name = $u['lname'] ?? NULL;
259 $password = $u['user_pass'] ?? NULL;
260 $user_bio = $u['user_bio'] ?? NULL;
261 $user_email = $u['user_email'] ?? NULL;
180b8ec1 262 $conn = sqlnew();
9a674833
VP
263 $prep = $conn->prepare("INSERT INTO " . SQL_PREFIX . "users (user_name, user_pass, user_fname, user_lname, user_bio, user_email, created) VALUES (:name, :pass, :fname, :lname, :user_bio, :user_email, :created)");
264 $prep->execute(["name" => $username, "pass" => $password, "fname" => $first_name, "lname" => $last_name, "user_bio" => $user_bio, "user_email" => $user_email, "created" => date("Y-m-d H:i:s")]);
180b8ec1
VP
265 if ($prep->rowCount())
266 $u['success'] = true;
267 else
268 $u['errmsg'][] = "Could not add user";
269 }
270
271 public static function get_user_list(&$list)
272 {
273 $conn = sqlnew();
274 $result = $conn->query("SELECT user_id FROM " . SQL_PREFIX . "users");
275 if (!$result) // impossible
276 {
277 die("Something went wrong.");
278 }
279 $userlist = [];
280 while($row = $result->fetch())
281 {
282 $userlist[] = new PanelUser(NULL, $row['user_id']);
283 }
284 if (!empty($userlist))
285 $list = $userlist;
286
287 }
288 public static function user_delete(&$u)
289 {
290 $user = $u['user'];
291 $query = "DELETE FROM " . SQL_PREFIX . "users WHERE user_id = :id";
292 $conn = sqlnew();
293 $stmt = $conn->prepare($query);
294 $stmt->execute(["id" => $user->id]);
295 $deleted = $stmt->rowCount();
296 if ($deleted)
297 {
298 $u['info'][] = "Successfully deleted user \"$user->username\"";
299 $u['boolint'] = 1;
300 } else {
301 $u['info'][] = "Unknown error";
302 $u['boolint'] = 0;
303 }
304 }
5a7f0cde
VP
305
306 public static function edit_core($arr)
307 {
308 $conn = sqlnew();
309 $user = $arr['user'];
310 $info = $arr['info'];
311 foreach($info as $key => $val)
312 {
e9c858fd 313 $value = NULL;
5a7f0cde
VP
314 if (!$val)
315 continue;
e9c858fd
VP
316 if (!strcmp($key,"update_fname") && $val != $user->first_name)
317 {
5a7f0cde 318 $value = "user_fname";
e9c858fd
VP
319 $valuestr = "first name";
320 }
321 elseif (!strcmp($key,"update_lname") && $val != $user->last_name)
322 {
5a7f0cde 323 $value = "user_lname";
e9c858fd
VP
324 $valuestr = "last name";
325 }
326 elseif (!strcmp($key,"update_bio") && $val != $user->bio)
327 {
5a7f0cde 328 $value = "user_bio";
e9c858fd
VP
329 $valuestr = "bio";
330 }
5a7f0cde 331 elseif (!strcmp($key,"update_pass") || !strcmp($key,"update_pass_conf"))
e9c858fd 332 {
5a7f0cde 333 $value = "user_pass";
e9c858fd
VP
334 $valuestr = "password";
335 }
336 elseif(!strcmp($key,"update_email") && $val != $user->email)
337 {
5a7f0cde 338 $value = "user_email";
e9c858fd
VP
339 $valuestr = "email address";
340 }
341
342 if (!$value)
343 continue;
5a7f0cde
VP
344 $query = "UPDATE " . SQL_PREFIX . "users SET $value=:value WHERE user_id = :id";
345 $stmt = $conn->prepare($query);
346 $stmt->execute(["value" => $val, "id" => $user->id]);
e9c858fd
VP
347
348 if (!$stmt->rowCount() && $stmt->errorInfo()[0] != "00000")
349 Message::Fail("Could not update $valuestr for $user->username: ".$stmt->errorInfo()[0]." (CODE: ".$stmt->errorCode().")");
350
351 else
352 Message::Success("Successfully updated the $valuestr for $user->username");
5a7f0cde
VP
353 }
354 }
ce9cf366
VP
355}
356
357
358function security_check()
359{
360 $ip = $_SERVER['REMOTE_ADDR'];
361 if (dnsbl_check($ip))
362 return true;
363
364 else if (fail2ban_check($ip))
365 {
366
367 }
368}
369
370function dnsbl_check($ip)
371{
5a7f0cde
VP
372
373 if (!defined('DNSBL'))
374 return;
ce9cf366
VP
375 $dnsbl_lookup = DNSBL;
376
377 // clear variable just in case
378 $listed = NULL;
379
380 // if the IP was not given because you're an idiot, stop processing
381 if (!$ip) { return; }
382
383 // get the first two segments of the IPv4
384 $because = split($ip, "."); // why you
385 $you = $because[1]; // gotta play
386 $want = $because[2]; // that song
387 $to = $you.".".$want."."; // so loud?
388
389 // exempt local connections because sometimes they get a false positive
390 if ($to == "192.168." || $to == "127.0.") { return NULL; }
391
392 // you spin my IP right round, right round, to check the records baby, right round-round-round
393 $reverse_ip = glue(array_reverse(split($ip, ".")), ".");
394
395 // checkem
396 foreach ($dnsbl_lookup as $host) {
397
398 //if it was listed
399 if (checkdnsrr($reverse_ip . "." . $host . ".", "A")) {
400
401 //take note
402 $listed = $host;
403 }
404 }
405
406 // if it was safe, return NOTHING
407 if (!$listed) {
408 return NULL;
409 }
410
411 // else, you guessed it, return where it was listed
412 else {
413 return $listed;
414 }
415}
416
417function fail2ban_check($ip)
33f512fa
VP
418{
419
420}