PageRenderTime 37ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/login.php

https://gitlab.com/LibreTitan/Panther
PHP | 297 lines | 213 code | 63 blank | 21 comment | 44 complexity | ba89ba0213ac3f789552be7c611bd18c MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright (C) 2015 Panther (https://www.pantherforum.org)
  4. * based on code by FluxBB copyright (C) 2008-2012 FluxBB
  5. * License: http://www.gnu.org/licenses/gpl.html GPL version 3 or higher
  6. */
  7. if (isset($_GET['action']))
  8. define('PANTHER_QUIET_VISIT', 1);
  9. if (!defined('PANTHER'))
  10. {
  11. define('PANTHER_ROOT', __DIR__.'/');
  12. require PANTHER_ROOT.'include/common.php';
  13. }
  14. if ($panther_user['is_bot']) // I can't think of one valid reason why bots should be able to attempt to login
  15. message($lang_common['No permission']);
  16. // Load the login.php language file
  17. require PANTHER_ROOT.'lang/'.$panther_user['language'].'/login.php';
  18. $action = isset($_GET['action']) ? $_GET['action'] : null;
  19. $errors = array();
  20. if (isset($_POST['form_sent']) && $action == 'in')
  21. {
  22. ($hook = get_extensions('login_before_validation')) ? eval($hook) : null;
  23. $form_username = isset($_POST['req_username']) ? panther_trim($_POST['req_username']) : '';
  24. $form_password = isset($_POST['req_password']) ? panther_trim($_POST['req_password']) : '';
  25. $save_pass = isset($_POST['save_pass']);
  26. if ($panther_config['o_login_queue'] == '1')
  27. {
  28. $data = array(
  29. ':username' => $form_username,
  30. ':timeout' => (TIMEOUT * 1000),
  31. );
  32. $ps = $db->select('login_queue', 'COUNT(*) AS overall, COUNT(IF(username = :username, TRUE, NULL)) AS user', $data, 'last_checked > NOW() - INTERVAL :timeout MICROSECOND');
  33. $count = $ps->fetch();
  34. if (!$count)
  35. message($lang_login['Unable to query size']);
  36. else if ($count['overall'] >= $panther_config['o_queue_size'] || $count['user'] >= $panther_config['o_max_attempts'])
  37. message($lang_login['Login queue exceeded']);
  38. $insert = array(
  39. 'ip_address' => get_remote_address(),
  40. 'username' => $form_username,
  41. );
  42. $db->insert('login_queue', $insert) or message($lang_login['IP address in queue']);
  43. $attempt = $db->lastInsertId($db->prefix.'login_queue');
  44. // This time, it's actually in our favour. Yes, I know!
  45. while (!check_queue($form_username, $attempt, $db))
  46. usleep(250 * 1000);
  47. //Force delay between logins, remove dead attempts
  48. usleep(ATTEMPT_DELAY * 1000);
  49. $data = array(
  50. ':id' => $attempt,
  51. ':timeout' => (TIMEOUT * 1000),
  52. );
  53. $db->delete('login_queue', 'id=:id OR last_checked < NOW() - INTERVAL :timeout MICROSECOND', $data);
  54. }
  55. $data = array(
  56. ':username' => $form_username,
  57. );
  58. $ps = $db->select('users', 'password, salt, group_id, id, login_key', $data, 'username=:username');
  59. $cur_user = $ps->fetch();
  60. if (!panther_hash_equals($cur_user['password'], panther_hash($form_password.$cur_user['salt'])))
  61. $errors[] = sprintf($lang_login['Wrong user/pass'], ' <a href="'.panther_link($panther_url['request_password']).'">'.$lang_login['Forgotten pass'].'</a>');
  62. ($hook = get_extensions('login_after_validation')) ? eval($hook) : null;
  63. if (empty($errors))
  64. {
  65. // Update the status if this is the first time the user logged in
  66. if ($cur_user['group_id'] == PANTHER_UNVERIFIED)
  67. {
  68. $update = array(
  69. 'group_id' => $panther_config['o_default_user_group'],
  70. );
  71. $data = array(
  72. ':id' => $cur_user['id'],
  73. );
  74. $db->update('users', $update, 'id=:id', $data);
  75. // Regenerate the users info cache
  76. if (!defined('FORUM_CACHE_FUNCTIONS_LOADED'))
  77. require PANTHER_ROOT.'include/cache.php';
  78. generate_users_info_cache();
  79. }
  80. // Remove this user's guest entry from the online list
  81. $data = array(
  82. ':ident' => get_remote_address(),
  83. );
  84. $db->delete('online', 'ident=:ident', $data);
  85. $expire = ($save_pass == '1') ? time() + 1209600 : time() + $panther_config['o_timeout_visit'];
  86. panther_setcookie($cur_user['id'], $cur_user['login_key'], $expire);
  87. // Reset tracked topics
  88. set_tracked_topics(null);
  89. // Try to determine if the data in redirect_url is valid (if not, we redirect to index.php after login)
  90. $redirect_url = validate_redirect($_POST['redirect_url'], panther_link($panther_url['index']));
  91. redirect($redirect_url, $lang_login['Login redirect']);
  92. }
  93. }
  94. else if ($action == 'out')
  95. {
  96. if ($panther_user['is_guest'] || !isset($_GET['id']) || $_GET['id'] != $panther_user['id'])
  97. {
  98. header('Location: '.panther_link($panther_url['index']));
  99. exit;
  100. }
  101. confirm_referrer('login.php');
  102. $data = array(
  103. ':id' => $panther_user['id'],
  104. );
  105. // Remove user from "users online" list
  106. $db->delete('online', 'user_id=:id', $data);
  107. generate_login_key();
  108. // Update last_visit (make sure there's something to update it with)
  109. if (isset($panther_user['logged']))
  110. {
  111. $update = array(
  112. 'last_visit' => $panther_user['logged'],
  113. );
  114. $data = array(
  115. ':id' => $panther_user['id'],
  116. );
  117. $db->update('users', $update, 'id=:id', $data);
  118. }
  119. panther_setcookie(1, panther_hash(uniqid(rand(), true)), time() + 31536000);
  120. redirect(panther_link($panther_url['index']), $lang_login['Logout redirect']);
  121. }
  122. else if ($action == 'forget')
  123. {
  124. if (!$panther_user['is_guest'])
  125. {
  126. header('Location: '.panther_link($panther_url['index']));
  127. exit;
  128. }
  129. if (isset($_POST['form_sent']))
  130. {
  131. confirm_referrer('login.php');
  132. ($hook = get_extensions('forget_password_before_validation')) ? eval($hook) : null;
  133. // Start with a clean slate
  134. $errors = array();
  135. require PANTHER_ROOT.'include/email.php';
  136. // Validate the email address
  137. $email = isset($_POST['req_email']) ? strtolower(panther_trim($_POST['req_email'])) : '';
  138. if (!$mailer->is_valid_email($email))
  139. $errors[] = $lang_common['Invalid email'];
  140. ($hook = get_extensions('forget_password_after_validation')) ? eval($hook) : null;
  141. // Did everything go according to plan?
  142. if (empty($errors))
  143. {
  144. $data = array(
  145. ':email' => $email,
  146. );
  147. $ps = $db->select('users', 'id, username, last_email_sent', $data, 'email=:email');
  148. if ($ps->rowCount())
  149. {
  150. // Loop through users we found
  151. foreach ($ps as $cur_hit)
  152. {
  153. if ($cur_hit['last_email_sent'] != '' && (time() - $cur_hit['last_email_sent']) < 3600 && (time() - $cur_hit['last_email_sent']) >= 0)
  154. message(sprintf($lang_login['Email flood'], intval((3600 - (time() - $cur_hit['last_email_sent'])) / 60)), true);
  155. // Generate a new password and a new password activation code
  156. $new_password = random_pass(12);
  157. $new_salt = random_pass(16);
  158. $new_password_key = random_pass(8);
  159. $update = array(
  160. 'activate_string' => panther_hash($new_password.$new_salt),
  161. 'salt' => $new_salt,
  162. 'activate_key' => $new_password_key,
  163. 'last_email_sent' => time(),
  164. );
  165. $data = array(
  166. ':id' => $cur_hit['id'],
  167. );
  168. $db->update('users', $update, 'id=:id', $data);
  169. $info = array(
  170. 'message' => array(
  171. '<base_url>' => get_base_url(),
  172. '<username>' => $cur_hit['username'],
  173. '<activation_url>' => panther_link($panther_url['change_password_key'], array($cur_hit['id'], $new_password_key)),
  174. '<new_password>' => $new_password,
  175. )
  176. );
  177. $mail_tpl = $mailer->parse(PANTHER_ROOT.'lang/'.$panther_user['language'].'/mail_templates/activate_password.tpl', $info);
  178. $mailer->send($email, $mail_tpl['subject'], $mail_tpl['message']);
  179. }
  180. message($lang_login['Forget mail'].' '.$panther_config['o_admin_email'], true);
  181. }
  182. else
  183. $errors[] = $lang_login['No email match'].' '.$email.'.';
  184. }
  185. }
  186. $page_title = array($panther_config['o_board_title'], $lang_login['Request pass']);
  187. $required_fields = array('req_email' => $lang_common['Email']);
  188. $focus_element = array('request_pass', 'req_email');
  189. ($hook = get_extensions('forgot_password_before_header')) ? eval($hook) : null;
  190. define ('PANTHER_ACTIVE_PAGE', 'login');
  191. require PANTHER_ROOT.'header.php';
  192. $tpl = load_template('forgot_password.tpl');
  193. echo $tpl->render(
  194. array (
  195. 'lang_login' => $lang_login,
  196. 'form_url' => panther_link($panther_url['request_password']),
  197. 'csrf_token' => generate_csrf_token(),
  198. 'lang_common' => $lang_common,
  199. 'errors' => $errors
  200. )
  201. );
  202. require PANTHER_ROOT.'footer.php';
  203. }
  204. if (!$panther_user['is_guest'])
  205. {
  206. header('Location: '.panther_link($panther_url['index']));
  207. exit;
  208. }
  209. // Try to determine if the data in HTTP_REFERER is valid (if not, we redirect to index.php after login)
  210. if (!empty($_SERVER['HTTP_REFERER']))
  211. $redirect_url = validate_redirect($_SERVER['HTTP_REFERER'], null);
  212. if (!isset($redirect_url))
  213. $redirect_url = panther_link($panther_url['index']);
  214. else if (preg_match('%viewtopic\.php\?pid=(\d+)$%', $redirect_url, $matches))
  215. $redirect_url .= '#p'.$matches[1];
  216. $page_title = array($panther_config['o_board_title'], $lang_common['Login']);
  217. $required_fields = array('req_username' => $lang_common['Username'], 'req_password' => $lang_common['Password']);
  218. $focus_element = array('login', 'req_username');
  219. ($hook = get_extensions('login_before_header')) ? eval($hook) : null;
  220. define('PANTHER_ACTIVE_PAGE', 'login');
  221. require PANTHER_ROOT.'header.php';
  222. $tpl = load_template('login.tpl');
  223. echo $tpl->render(
  224. array (
  225. 'lang_login' => $lang_login,
  226. 'lang_common' => $lang_common,
  227. 'form_action' => panther_link($panther_url['login_in']),
  228. 'redirect_url' => $redirect_url,
  229. 'register' => panther_link($panther_url['register']),
  230. 'request_password' => panther_link($panther_url['request_password']),
  231. 'errors' => $errors,
  232. )
  233. );
  234. require PANTHER_ROOT.'footer.php';