index.php 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. <?php
  2. use function Hestiacp\quoteshellarg\quoteshellarg;
  3. // Init
  4. define('NO_AUTH_REQUIRED',true);
  5. define('NO_AUTH_REQUIRED2',true);
  6. header('Content-Type: text/plain; charset=utf-8');
  7. include($_SERVER['DOCUMENT_ROOT']."/inc/main.php");
  8. // Checking IP of incoming connection, checking is it NAT address
  9. $ok=0;
  10. $ip=$_SERVER['REMOTE_ADDR'];
  11. exec (HESTIA_CMD."v-list-sys-ips json", $output, $return_var);
  12. $output=implode('', $output);
  13. $arr=json_decode($output, true);
  14. foreach ($arr as $arr_key => $arr_val) {
  15. // search for NAT IPs and allow them
  16. if ($ip==$arr_key || $ip==$arr_val['NAT']) {
  17. $ok=1;
  18. break;
  19. }
  20. }
  21. if ($ip == $_SERVER['SERVER_ADDR']) $ok=1;
  22. if ($ip == '127.0.0.1') $ok=1;
  23. if ($ok==0) exit;
  24. if (isset($_SERVER['HTTP_X_REAL_IP']) || isset($_SERVER['HTTP_X_FORWARDED_FOR'])) exit;
  25. // Check arguments
  26. if (empty($_POST['email'])) {
  27. echo "error email address not provided";
  28. exit;
  29. }
  30. if (empty($_POST['password'])) {
  31. echo "error old password provided";
  32. exit;
  33. }
  34. if (empty($_POST['new'])) {
  35. echo "error new password not provided";
  36. exit;
  37. }
  38. list($v_account, $v_domain) = explode('@', $_POST['email']);
  39. $v_domain = quoteshellarg($v_domain);
  40. $v_account = quoteshellarg($v_account);
  41. $v_password = $_POST['password'];
  42. // Get domain owner
  43. exec(HESTIA_CMD . "v-search-domain-owner " . $v_domain . " 'mail'", $output, $return_var);
  44. if ($return_var != 0 || empty($output[0])) {
  45. echo "error domain owner not found";
  46. exit;
  47. }
  48. $v_user = $output[0];
  49. unset($output);
  50. // Get current password hash (called "md5" for legacy reasons, it's not guaranteed to be md5)
  51. exec(HESTIA_CMD . "v-get-mail-account-value " . quoteshellarg($v_user) . " " . $v_domain . " " . $v_account . " 'md5'", $output, $return_var);
  52. if ($return_var != 0 || empty($output[0])) {
  53. echo "error unable to get current account password hash";
  54. exit;
  55. }
  56. $v_hash = $output[0];
  57. unset($output);
  58. // v_hash use doveadm password hash format, which is basically {HASH_NAME}normal_crypt_format,
  59. // so we just need to remove the {HASH_NAME} before we can ask password_verify if its correct or not.
  60. $hash_for_password_verify = explode('}', $v_hash, 2);
  61. $hash_for_password_verify = end($hash_for_password_verify);
  62. if (!password_verify($v_password, $hash_for_password_verify)) {
  63. die("error old password does not match");
  64. }
  65. // Change password
  66. $fp = tmpfile();
  67. $new_password_file = stream_get_meta_data($fp)['uri'];
  68. fwrite($fp, $_POST['new'] . "\n");
  69. exec(HESTIA_CMD . "v-change-mail-account-password " . quoteshellarg($v_user) . " " . $v_domain . " " . $v_account . " " . quoteshellarg($new_password_file), $output, $return_var);
  70. fclose($fp);
  71. if ($return_var == 0) {
  72. echo "==ok==";
  73. exit;
  74. }
  75. echo 'error v-change-mail-account-password returned non-zero: ' . $return_var;
  76. exit;