index.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <?php
  2. use function Hestiacp\quoteshellarg\quoteshellarg;
  3. define("NO_AUTH_REQUIRED", true);
  4. $TAB = "RESET PASSWORD";
  5. // Main include
  6. include $_SERVER["DOCUMENT_ROOT"] . "/inc/main.php";
  7. if (isset($_SESSION["user"])) {
  8. header("Location: /list/user");
  9. }
  10. if ($_SESSION["POLICY_SYSTEM_PASSWORD_RESET"] == "no") {
  11. header("Location: /login/");
  12. exit();
  13. }
  14. if (!empty($_POST["user"]) && empty($_POST["code"])) {
  15. // Check token
  16. verify_csrf($_POST);
  17. $v_user = quoteshellarg($_POST["user"]);
  18. $user = $_POST["user"];
  19. $email = $_POST["email"];
  20. $cmd = "/usr/bin/sudo /usr/local/hestia/bin/v-list-user";
  21. exec($cmd . " " . $v_user . " json", $output, $return_var);
  22. if ($return_var == 0) {
  23. $data = json_decode(implode("", $output), true);
  24. unset($output);
  25. exec(HESTIA_CMD . "v-get-user-value " . $v_user . " RKEYEXP", $output, $return_var);
  26. $rkeyexp = json_decode(implode("", $output), true);
  27. if ($rkeyexp === null || $rkeyexp < time() - 1) {
  28. if ($email == $data[$user]["CONTACT"]) {
  29. $rkey = substr(password_hash("", PASSWORD_DEFAULT), 8, 12);
  30. $hash = password_hash($rkey, PASSWORD_DEFAULT);
  31. $v_rkey = tempnam("/tmp", "vst");
  32. $fp = fopen($v_rkey, "w");
  33. fwrite($fp, $hash . "\n");
  34. fclose($fp);
  35. exec(
  36. HESTIA_CMD . "v-change-user-rkey " . $v_user . " " . $v_rkey . "",
  37. $output,
  38. $return_var,
  39. );
  40. unset($output);
  41. unlink($v_rkey);
  42. $name = $data[$user]["NAME"];
  43. $contact = $data[$user]["CONTACT"];
  44. $to = $data[$user]["CONTACT"];
  45. $subject = sprintf(_("MAIL_RESET_SUBJECT"), date("Y-m-d H:i:s"));
  46. $hostname = get_hostname();
  47. if ($hostname . ":" . $_SERVER["SERVER_PORT"] == $_SERVER["HTTP_HOST"]) {
  48. $check = true;
  49. $hostname_email = $hostname;
  50. } elseif ($hostname_full . ":" . $_SERVER["SERVER_PORT"] == $_SERVER["HTTP_HOST"]) {
  51. $check = true;
  52. $hostname_email = $hostname_full;
  53. } else {
  54. $check = false;
  55. $ERROR = "<p class=\"error\">" . _("Invalid host domain") . "</p>";
  56. }
  57. if ($check == true) {
  58. $from = "noreply@" . $hostname;
  59. $from_name = _("Hestia Control Panel");
  60. if (!empty($name)) {
  61. $mailtext = sprintf(_("GREETINGS_GORDON"), $name);
  62. } else {
  63. $mailtext = _("GREETINGS");
  64. }
  65. $mailtext .= sprintf(
  66. _("PASSWORD_RESET_REQUEST"),
  67. $_SERVER["HTTP_HOST"],
  68. $user,
  69. $rkey,
  70. $_SERVER["HTTP_HOST"],
  71. $user,
  72. $rkey,
  73. );
  74. if (!empty($rkey)) {
  75. send_email(
  76. $to,
  77. $subject,
  78. $mailtext,
  79. $from,
  80. $from_name,
  81. $data[$user]["NAME"],
  82. );
  83. }
  84. $ERROR =
  85. "<p class=\"error\">" .
  86. _(
  87. "Password reset instructions have been sent to the email address associated with this account.",
  88. ) .
  89. "</p>";
  90. }
  91. } else {
  92. # Prevent user enumeration and let hackers guess username and working email
  93. $ERROR =
  94. "<p class=\"error\">" .
  95. _(
  96. "Password reset instructions have been sent to the email address associated with this account.",
  97. ) .
  98. "</p>";
  99. }
  100. } else {
  101. $ERROR =
  102. "<p class=\"error\">" .
  103. _("Please wait 15 minutes before sending a new request") .
  104. "</p>";
  105. }
  106. } else {
  107. # Prevent user enumeration and let hackers guess username and working email
  108. $ERROR =
  109. "<p class=\"error\">" .
  110. _(
  111. "Password reset instructions have been sent to the email address associated with this account.",
  112. ) .
  113. "</p>";
  114. }
  115. unset($output);
  116. }
  117. if (!empty($_POST["user"]) && !empty($_POST["code"]) && !empty($_POST["password"])) {
  118. // Check token
  119. verify_csrf($_POST);
  120. if ($_POST["password"] == $_POST["password_confirm"]) {
  121. $v_user = quoteshellarg($_POST["user"]);
  122. $user = $_POST["user"];
  123. exec(HESTIA_CMD . "v-list-user " . $v_user . " json", $output, $return_var);
  124. if ($return_var == 0) {
  125. $data = json_decode(implode("", $output), true);
  126. $rkey = $data[$user]["RKEY"];
  127. if (password_verify($_POST["code"], $rkey)) {
  128. unset($output);
  129. exec(HESTIA_CMD . "v-get-user-value " . $v_user . " RKEYEXP", $output, $return_var);
  130. if ($output[0] > time() - 900) {
  131. $v_password = tempnam("/tmp", "vst");
  132. $fp = fopen($v_password, "w");
  133. fwrite($fp, $_POST["password"] . "\n");
  134. fclose($fp);
  135. exec(
  136. HESTIA_CMD . "v-change-user-password " . $v_user . " " . $v_password,
  137. $output,
  138. $return_var,
  139. );
  140. unlink($v_password);
  141. if ($return_var > 0) {
  142. sleep(5);
  143. $ERROR = "<p class=\"error\">" . _("An internal error occurred") . "</p>";
  144. } else {
  145. $_SESSION["user"] = $_POST["user"];
  146. header("Location: /");
  147. exit();
  148. }
  149. } else {
  150. sleep(5);
  151. $ERROR = "<p class=\"error\">" . _("Code has been expired") . "</p>";
  152. exec(
  153. HESTIA_CMD .
  154. "v-log-user-login " .
  155. $v_user .
  156. " " .
  157. $v_ip .
  158. " failed " .
  159. $v_session_id .
  160. " " .
  161. $v_user_agent .
  162. ' yes "Reset code has been expired"',
  163. $output,
  164. $return_var,
  165. );
  166. }
  167. } else {
  168. sleep(5);
  169. $ERROR = "<p class=\"error\">" . _("Invalid username or code") . "</p>";
  170. exec(
  171. HESTIA_CMD .
  172. "v-log-user-login " .
  173. $v_user .
  174. " " .
  175. $v_ip .
  176. " failed " .
  177. $v_session_id .
  178. " " .
  179. $v_user_agent .
  180. ' yes "Invalid Username or Code"',
  181. $output,
  182. $return_var,
  183. );
  184. }
  185. } else {
  186. sleep(5);
  187. $ERROR = "<p class=\"error\">" . _("Invalid username or code") . "</p>";
  188. }
  189. } else {
  190. $ERROR = "<p class=\"error\">" . _("Passwords not match") . "</p>";
  191. }
  192. }
  193. if (empty($_GET["action"])) {
  194. require_once "../templates/header.php";
  195. require_once "../templates/pages/login/reset_1.php";
  196. } else {
  197. require_once "../templates/header.php";
  198. if ($_GET["action"] == "code") {
  199. require_once "../templates/pages/login/reset_2.php";
  200. }
  201. if ($_GET["action"] == "confirm" && !empty($_GET["code"])) {
  202. require_once "../templates/pages/login/reset_3.php";
  203. }
  204. }