You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					250 lines
				
				7.3 KiB
			
		
		
			
		
	
	
					250 lines
				
				7.3 KiB
			| 
								 
											2 years ago
										 
									 | 
							
								<?php
							 | 
						||
| 
								 | 
							
								use function Hestiacp\quoteshellarg\quoteshellarg;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								define("NO_AUTH_REQUIRED", true);
							 | 
						||
| 
								 | 
							
								$TAB = "RESET PASSWORD";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Main include
							 | 
						||
| 
								 | 
							
								include $_SERVER["DOCUMENT_ROOT"] . "/inc/main.php";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if (isset($_SESSION["user"])) {
							 | 
						||
| 
								 | 
							
									header("Location: /list/user");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if ($_SESSION["POLICY_SYSTEM_PASSWORD_RESET"] == "no") {
							 | 
						||
| 
								 | 
							
									header("Location: /login/");
							 | 
						||
| 
								 | 
							
									exit();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if (!empty($_POST["user"]) && empty($_POST["code"])) {
							 | 
						||
| 
								 | 
							
									// Check token
							 | 
						||
| 
								 | 
							
									verify_csrf($_POST);
							 | 
						||
| 
								 | 
							
									$v_user = quoteshellarg($_POST["user"]);
							 | 
						||
| 
								 | 
							
									$user = $_POST["user"];
							 | 
						||
| 
								 | 
							
									$email = $_POST["email"];
							 | 
						||
| 
								 | 
							
									$cmd = "/usr/bin/sudo /usr/local/hestia/bin/v-list-user";
							 | 
						||
| 
								 | 
							
									exec($cmd . " " . $v_user . " json", $output, $return_var);
							 | 
						||
| 
								 | 
							
									if ($return_var == 0) {
							 | 
						||
| 
								 | 
							
										$data = json_decode(implode("", $output), true);
							 | 
						||
| 
								 | 
							
										unset($output);
							 | 
						||
| 
								 | 
							
										exec(HESTIA_CMD . "v-get-user-value " . $v_user . " RKEYEXP", $output, $return_var);
							 | 
						||
| 
								 | 
							
										$rkeyexp = json_decode(implode("", $output), true);
							 | 
						||
| 
								 | 
							
										if ($rkeyexp === null || $rkeyexp < time() - 1) {
							 | 
						||
| 
								 | 
							
											if ($email == $data[$user]["CONTACT"]) {
							 | 
						||
| 
								 | 
							
												$rkey = substr(password_hash("", PASSWORD_DEFAULT), 8, 12);
							 | 
						||
| 
								 | 
							
												$hash = password_hash($rkey, PASSWORD_DEFAULT);
							 | 
						||
| 
								 | 
							
												$v_rkey = tempnam("/tmp", "vst");
							 | 
						||
| 
								 | 
							
												$fp = fopen($v_rkey, "w");
							 | 
						||
| 
								 | 
							
												fwrite($fp, $hash . "\n");
							 | 
						||
| 
								 | 
							
												fclose($fp);
							 | 
						||
| 
								 | 
							
												exec(
							 | 
						||
| 
								 | 
							
													HESTIA_CMD . "v-change-user-rkey " . $v_user . " " . $v_rkey . "",
							 | 
						||
| 
								 | 
							
													$output,
							 | 
						||
| 
								 | 
							
													$return_var,
							 | 
						||
| 
								 | 
							
												);
							 | 
						||
| 
								 | 
							
												unset($output);
							 | 
						||
| 
								 | 
							
												unlink($v_rkey);
							 | 
						||
| 
								 | 
							
												$template = get_email_template("reset_password", $data[$user]["LANGUAGE"]);
							 | 
						||
| 
								 | 
							
												if (!empty($template)) {
							 | 
						||
| 
								 | 
							
													preg_match("/<subject>(.*?)<\/subject>/si", $template, $matches);
							 | 
						||
| 
								 | 
							
													$subject = $matches[1];
							 | 
						||
| 
								 | 
							
													$subject = str_replace(
							 | 
						||
| 
								 | 
							
														["{{date}}", "{{hostname}}", "{{appname}}", "{{user}}"],
							 | 
						||
| 
								 | 
							
														[date("Y-m-d H:i:s"), get_hostname(), $_SESSION["APP_NAME"], $user],
							 | 
						||
| 
								 | 
							
														$subject,
							 | 
						||
| 
								 | 
							
													);
							 | 
						||
| 
								 | 
							
													$template = str_replace($matches[0], "", $template);
							 | 
						||
| 
								 | 
							
												} else {
							 | 
						||
| 
								 | 
							
													putenv("LANGUAGE=" . $data[$user]["LANGUAGE"]);
							 | 
						||
| 
								 | 
							
													$template = _(
							 | 
						||
| 
								 | 
							
														"Hello {{name}},\n" .
							 | 
						||
| 
								 | 
							
															"\n" .
							 | 
						||
| 
								 | 
							
															"To reset your {{appname}} password, please follow this link:\n" .
							 | 
						||
| 
								 | 
							
															"https://{{hostname}}/reset/?action=confirm&user={{user}}&code={{resetcode}}\n" .
							 | 
						||
| 
								 | 
							
															"\n" .
							 | 
						||
| 
								 | 
							
															"Alternatively, you may go to https://{{hostname}}/reset/?action=code&user={{user}} and enter the following reset code:\n" .
							 | 
						||
| 
								 | 
							
															"{{resetcode}}\n" .
							 | 
						||
| 
								 | 
							
															"\n" .
							 | 
						||
| 
								 | 
							
															"If you did not request password reset, please ignore this message and accept our apologies.\n" .
							 | 
						||
| 
								 | 
							
															"\n" .
							 | 
						||
| 
								 | 
							
															"Best regards,\n" .
							 | 
						||
| 
								 | 
							
															"\n" .
							 | 
						||
| 
								 | 
							
															"--\n" .
							 | 
						||
| 
								 | 
							
															"{{appname}}",
							 | 
						||
| 
								 | 
							
													);
							 | 
						||
| 
								 | 
							
													putenv("LANGUAGE=" . detect_user_language());
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												$name = $data[$user]["NAME"];
							 | 
						||
| 
								 | 
							
												$contact = $data[$user]["CONTACT"];
							 | 
						||
| 
								 | 
							
												$to = $data[$user]["CONTACT"];
							 | 
						||
| 
								 | 
							
												if (empty($subject)) {
							 | 
						||
| 
								 | 
							
													$subject = str_replace(
							 | 
						||
| 
								 | 
							
														["{{subject}}", "{{hostname}}", "{{appname}}"],
							 | 
						||
| 
								 | 
							
														[
							 | 
						||
| 
								 | 
							
															sprintf(_("Password Reset at %s"), date("Y-m-d H:i:s")),
							 | 
						||
| 
								 | 
							
															get_hostname(),
							 | 
						||
| 
								 | 
							
															$_SESSION["APP_NAME"],
							 | 
						||
| 
								 | 
							
														],
							 | 
						||
| 
								 | 
							
														$_SESSION["SUBJECT_EMAIL"],
							 | 
						||
| 
								 | 
							
													);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												$hostname = get_hostname();
							 | 
						||
| 
								 | 
							
												if ($hostname) {
							 | 
						||
| 
								 | 
							
													$host = preg_replace(
							 | 
						||
| 
								 | 
							
														"/(\[?[^]]*\]?):([0-9]{1,5})$/",
							 | 
						||
| 
								 | 
							
														"$1",
							 | 
						||
| 
								 | 
							
														$_SERVER["HTTP_HOST"],
							 | 
						||
| 
								 | 
							
													);
							 | 
						||
| 
								 | 
							
													if ($host == $hostname) {
							 | 
						||
| 
								 | 
							
														$port_is_defined = preg_match(
							 | 
						||
| 
								 | 
							
															"/\[?[^]]*\]?:[0-9]{1,5}$/",
							 | 
						||
| 
								 | 
							
															$_SERVER["HTTP_HOST"],
							 | 
						||
| 
								 | 
							
														);
							 | 
						||
| 
								 | 
							
														if ($port_is_defined) {
							 | 
						||
| 
								 | 
							
															$port =
							 | 
						||
| 
								 | 
							
																":" .
							 | 
						||
| 
								 | 
							
																preg_replace(
							 | 
						||
| 
								 | 
							
																	"/(\[?[^]]*\]?):([0-9]{1,5})$/",
							 | 
						||
| 
								 | 
							
																	"$2",
							 | 
						||
| 
								 | 
							
																	$_SERVER["HTTP_HOST"],
							 | 
						||
| 
								 | 
							
																);
							 | 
						||
| 
								 | 
							
														} else {
							 | 
						||
| 
								 | 
							
															$port = "";
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													} else {
							 | 
						||
| 
								 | 
							
														$port = ":" . $_SERVER["SERVER_PORT"];
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													$from = !empty($_SESSION["FROM_EMAIL"])
							 | 
						||
| 
								 | 
							
														? $_SESSION["FROM_EMAIL"]
							 | 
						||
| 
								 | 
							
														: "noreply@" . $hostname;
							 | 
						||
| 
								 | 
							
													$from_name = !empty($_SESSION["FROM_NAME"])
							 | 
						||
| 
								 | 
							
														? $_SESSION["FROM_NAME"]
							 | 
						||
| 
								 | 
							
														: $_SESSION["APP_NAME"];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													putenv("LANGUAGE=" . $data[$user]["LANGUAGE"]);
							 | 
						||
| 
								 | 
							
													$name = empty($data[$user]["NAME"]) ? $user : $data[$user]["NAME"];
							 | 
						||
| 
								 | 
							
													$mailtext = translate_email($template, [
							 | 
						||
| 
								 | 
							
														"name" => htmlentities($name),
							 | 
						||
| 
								 | 
							
														"hostname" => htmlentities($hostname . $port),
							 | 
						||
| 
								 | 
							
														"user" => htmlentities($user),
							 | 
						||
| 
								 | 
							
														"resetcode" => htmlentities($rkey),
							 | 
						||
| 
								 | 
							
														"appname" => $_SESSION["APP_NAME"],
							 | 
						||
| 
								 | 
							
													]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													send_email($to, $subject, $mailtext, $from, $from_name, $data[$user]["NAME"]);
							 | 
						||
| 
								 | 
							
													putenv("LANGUAGE=" . detect_user_language());
							 | 
						||
| 
								 | 
							
													$error = _(
							 | 
						||
| 
								 | 
							
														"Password reset instructions have been sent to the email address associated with this account.",
							 | 
						||
| 
								 | 
							
													);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												$error = _(
							 | 
						||
| 
								 | 
							
													"Password reset instructions have been sent to the email address associated with this account.",
							 | 
						||
| 
								 | 
							
												);
							 | 
						||
| 
								 | 
							
											} else {
							 | 
						||
| 
								 | 
							
												# Prevent user enumeration and let hackers guess username and working email
							 | 
						||
| 
								 | 
							
												$error = _(
							 | 
						||
| 
								 | 
							
													"Password reset instructions have been sent to the email address associated with this account.",
							 | 
						||
| 
								 | 
							
												);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										} else {
							 | 
						||
| 
								 | 
							
											$error = _("Please wait 15 minutes before sending a new request.");
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									} else {
							 | 
						||
| 
								 | 
							
										# Prevent user enumeration and let hackers guess username and working email
							 | 
						||
| 
								 | 
							
										$error = _(
							 | 
						||
| 
								 | 
							
											"Password reset instructions have been sent to the email address associated with this account.",
							 | 
						||
| 
								 | 
							
										);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									unset($output);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if (!empty($_POST["user"]) && !empty($_POST["code"]) && !empty($_POST["password"])) {
							 | 
						||
| 
								 | 
							
									// Check token
							 | 
						||
| 
								 | 
							
									verify_csrf($_POST);
							 | 
						||
| 
								 | 
							
									if ($_POST["password"] == $_POST["password_confirm"]) {
							 | 
						||
| 
								 | 
							
										$v_user = quoteshellarg($_POST["user"]);
							 | 
						||
| 
								 | 
							
										$user = $_POST["user"];
							 | 
						||
| 
								 | 
							
										exec(HESTIA_CMD . "v-list-user " . $v_user . " json", $output, $return_var);
							 | 
						||
| 
								 | 
							
										if ($return_var == 0) {
							 | 
						||
| 
								 | 
							
											$data = json_decode(implode("", $output), true);
							 | 
						||
| 
								 | 
							
											$rkey = $data[$user]["RKEY"];
							 | 
						||
| 
								 | 
							
											if (password_verify($_POST["code"], $rkey)) {
							 | 
						||
| 
								 | 
							
												unset($output);
							 | 
						||
| 
								 | 
							
												exec(HESTIA_CMD . "v-get-user-value " . $v_user . " RKEYEXP", $output, $return_var);
							 | 
						||
| 
								 | 
							
												if ($output[0] > time() - 900) {
							 | 
						||
| 
								 | 
							
													$v_password = tempnam("/tmp", "vst");
							 | 
						||
| 
								 | 
							
													$fp = fopen($v_password, "w");
							 | 
						||
| 
								 | 
							
													fwrite($fp, $_POST["password"] . "\n");
							 | 
						||
| 
								 | 
							
													fclose($fp);
							 | 
						||
| 
								 | 
							
													exec(
							 | 
						||
| 
								 | 
							
														HESTIA_CMD . "v-change-user-password " . $v_user . " " . $v_password,
							 | 
						||
| 
								 | 
							
														$output,
							 | 
						||
| 
								 | 
							
														$return_var,
							 | 
						||
| 
								 | 
							
													);
							 | 
						||
| 
								 | 
							
													unlink($v_password);
							 | 
						||
| 
								 | 
							
													if ($return_var > 0) {
							 | 
						||
| 
								 | 
							
														sleep(5);
							 | 
						||
| 
								 | 
							
														$error = _("An internal error occurred");
							 | 
						||
| 
								 | 
							
													} else {
							 | 
						||
| 
								 | 
							
														$_SESSION["user"] = $_POST["user"];
							 | 
						||
| 
								 | 
							
														header("Location: /");
							 | 
						||
| 
								 | 
							
														exit();
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												} else {
							 | 
						||
| 
								 | 
							
													sleep(5);
							 | 
						||
| 
								 | 
							
													$error = _("Code has been expired");
							 | 
						||
| 
								 | 
							
													exec(
							 | 
						||
| 
								 | 
							
														HESTIA_CMD .
							 | 
						||
| 
								 | 
							
															"v-log-user-login " .
							 | 
						||
| 
								 | 
							
															$v_user .
							 | 
						||
| 
								 | 
							
															" " .
							 | 
						||
| 
								 | 
							
															$v_ip .
							 | 
						||
| 
								 | 
							
															" failed " .
							 | 
						||
| 
								 | 
							
															$v_session_id .
							 | 
						||
| 
								 | 
							
															" " .
							 | 
						||
| 
								 | 
							
															$v_user_agent .
							 | 
						||
| 
								 | 
							
															' yes "Reset code has been expired"',
							 | 
						||
| 
								 | 
							
														$output,
							 | 
						||
| 
								 | 
							
														$return_var,
							 | 
						||
| 
								 | 
							
													);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											} else {
							 | 
						||
| 
								 | 
							
												sleep(5);
							 | 
						||
| 
								 | 
							
												$error = _("Invalid username or code");
							 | 
						||
| 
								 | 
							
												exec(
							 | 
						||
| 
								 | 
							
													HESTIA_CMD .
							 | 
						||
| 
								 | 
							
														"v-log-user-login " .
							 | 
						||
| 
								 | 
							
														$v_user .
							 | 
						||
| 
								 | 
							
														" " .
							 | 
						||
| 
								 | 
							
														$v_ip .
							 | 
						||
| 
								 | 
							
														" failed " .
							 | 
						||
| 
								 | 
							
														$v_session_id .
							 | 
						||
| 
								 | 
							
														" " .
							 | 
						||
| 
								 | 
							
														$v_user_agent .
							 | 
						||
| 
								 | 
							
														' yes "Invalid Username or Code"',
							 | 
						||
| 
								 | 
							
													$output,
							 | 
						||
| 
								 | 
							
													$return_var,
							 | 
						||
| 
								 | 
							
												);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										} else {
							 | 
						||
| 
								 | 
							
											sleep(5);
							 | 
						||
| 
								 | 
							
											$error = _("Invalid username or code");
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									} else {
							 | 
						||
| 
								 | 
							
										$error = _("Passwords do not match");
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if (empty($_GET["action"])) {
							 | 
						||
| 
								 | 
							
									require_once "../templates/header.php";
							 | 
						||
| 
								 | 
							
									require_once "../templates/pages/login/reset_1.php";
							 | 
						||
| 
								 | 
							
								} else {
							 | 
						||
| 
								 | 
							
									require_once "../templates/header.php";
							 | 
						||
| 
								 | 
							
									if ($_GET["action"] == "code") {
							 | 
						||
| 
								 | 
							
										require_once "../templates/pages/login/reset_2.php";
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if ($_GET["action"] == "confirm" && !empty($_GET["code"])) {
							 | 
						||
| 
								 | 
							
										require_once "../templates/pages/login/reset_3.php";
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |