index.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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) {
  48. $host = preg_replace(
  49. "/(\[?[^]]*\]?):([0-9]{1,5})$/",
  50. "$1",
  51. $_SERVER["HTTP_HOST"],
  52. );
  53. if ($host == $hostname) {
  54. $port_is_defined = preg_match(
  55. "/\[?[^]]*\]?:[0-9]{1,5}$/",
  56. $_SERVER["HTTP_HOST"],
  57. );
  58. if ($port_is_defined) {
  59. $port = preg_replace(
  60. "/(\[?[^]]*\]?):([0-9]{1,5})$/",
  61. "$2",
  62. $_SERVER["HTTP_HOST"],
  63. );
  64. } else {
  65. $port = "";
  66. }
  67. } else {
  68. $port = ":" . $_SERVER["SERVER_PORT"];
  69. }
  70. $from = "noreply@" . $hostname;
  71. $from_name = _("Hestia Control Panel");
  72. if (!empty($name)) {
  73. $mailtext = sprintf(_("GREETINGS_GORDON"), $name);
  74. } else {
  75. $mailtext = _("GREETINGS");
  76. }
  77. $mailtext .= sprintf(
  78. _("PASSWORD_RESET_REQUEST"),
  79. $hostname . $port,
  80. $user,
  81. $rkey,
  82. $hostname . $port,
  83. $user,
  84. $rkey,
  85. );
  86. if (!empty($rkey)) {
  87. send_email(
  88. $to,
  89. $subject,
  90. $mailtext,
  91. $from,
  92. $from_name,
  93. $data[$user]["NAME"],
  94. );
  95. }
  96. }
  97. $ERROR =
  98. "<p class=\"error\">" .
  99. _(
  100. "Password reset instructions have been sent to the email address associated with this account.",
  101. ) .
  102. "</p>";
  103. } else {
  104. # Prevent user enumeration and let hackers guess username and working email
  105. $ERROR =
  106. "<p class=\"error\">" .
  107. _(
  108. "Password reset instructions have been sent to the email address associated with this account.",
  109. ) .
  110. "</p>";
  111. }
  112. } else {
  113. $ERROR =
  114. "<p class=\"error\">" .
  115. _("Please wait 15 minutes before sending a new request") .
  116. "</p>";
  117. }
  118. } else {
  119. # Prevent user enumeration and let hackers guess username and working email
  120. $ERROR =
  121. "<p class=\"error\">" .
  122. _(
  123. "Password reset instructions have been sent to the email address associated with this account.",
  124. ) .
  125. "</p>";
  126. }
  127. unset($output);
  128. }
  129. if (!empty($_POST["user"]) && !empty($_POST["code"]) && !empty($_POST["password"])) {
  130. // Check token
  131. verify_csrf($_POST);
  132. if ($_POST["password"] == $_POST["password_confirm"]) {
  133. $v_user = quoteshellarg($_POST["user"]);
  134. $user = $_POST["user"];
  135. exec(HESTIA_CMD . "v-list-user " . $v_user . " json", $output, $return_var);
  136. if ($return_var == 0) {
  137. $data = json_decode(implode("", $output), true);
  138. $rkey = $data[$user]["RKEY"];
  139. if (password_verify($_POST["code"], $rkey)) {
  140. unset($output);
  141. exec(HESTIA_CMD . "v-get-user-value " . $v_user . " RKEYEXP", $output, $return_var);
  142. if ($output[0] > time() - 900) {
  143. $v_password = tempnam("/tmp", "vst");
  144. $fp = fopen($v_password, "w");
  145. fwrite($fp, $_POST["password"] . "\n");
  146. fclose($fp);
  147. exec(
  148. HESTIA_CMD . "v-change-user-password " . $v_user . " " . $v_password,
  149. $output,
  150. $return_var,
  151. );
  152. unlink($v_password);
  153. if ($return_var > 0) {
  154. sleep(5);
  155. $ERROR = "<p class=\"error\">" . _("An internal error occurred") . "</p>";
  156. } else {
  157. $_SESSION["user"] = $_POST["user"];
  158. header("Location: /");
  159. exit();
  160. }
  161. } else {
  162. sleep(5);
  163. $ERROR = "<p class=\"error\">" . _("Code has been expired") . "</p>";
  164. exec(
  165. HESTIA_CMD .
  166. "v-log-user-login " .
  167. $v_user .
  168. " " .
  169. $v_ip .
  170. " failed " .
  171. $v_session_id .
  172. " " .
  173. $v_user_agent .
  174. ' yes "Reset code has been expired"',
  175. $output,
  176. $return_var,
  177. );
  178. }
  179. } else {
  180. sleep(5);
  181. $ERROR = "<p class=\"error\">" . _("Invalid username or code") . "</p>";
  182. exec(
  183. HESTIA_CMD .
  184. "v-log-user-login " .
  185. $v_user .
  186. " " .
  187. $v_ip .
  188. " failed " .
  189. $v_session_id .
  190. " " .
  191. $v_user_agent .
  192. ' yes "Invalid Username or Code"',
  193. $output,
  194. $return_var,
  195. );
  196. }
  197. } else {
  198. sleep(5);
  199. $ERROR = "<p class=\"error\">" . _("Invalid username or code") . "</p>";
  200. }
  201. } else {
  202. $ERROR = "<p class=\"error\">" . _("Passwords not match") . "</p>";
  203. }
  204. }
  205. if (empty($_GET["action"])) {
  206. require_once "../templates/header.php";
  207. require_once "../templates/pages/login/reset_1.php";
  208. } else {
  209. require_once "../templates/header.php";
  210. if ($_GET["action"] == "code") {
  211. require_once "../templates/pages/login/reset_2.php";
  212. }
  213. if ($_GET["action"] == "confirm" && !empty($_GET["code"])) {
  214. require_once "../templates/pages/login/reset_3.php";
  215. }
  216. }