|
2 | 2 | // Init |
3 | 3 | define('NO_AUTH_REQUIRED',true); |
4 | 4 | define('NO_AUTH_REQUIRED2',true); |
| 5 | +header('Content-Type: text/plain; charset=utf-8'); |
5 | 6 |
|
6 | 7 | include($_SERVER['DOCUMENT_ROOT']."/inc/main.php"); |
7 | 8 |
|
8 | 9 | // Checking IP of incoming connection, checking is it NAT address |
9 | 10 | $ok=0; |
10 | 11 | $ip=$_SERVER['REMOTE_ADDR']; |
| 12 | + |
11 | 13 | exec (HESTIA_CMD."v-list-sys-ips json", $output, $return_var); |
12 | 14 | $output=implode('', $output); |
13 | 15 | $arr=json_decode($output, true); |
|
24 | 26 | if (isset($_SERVER['HTTP_X_REAL_IP']) || isset($_SERVER['HTTP_X_FORWARDED_FOR'])) exit; |
25 | 27 |
|
26 | 28 |
|
27 | | -/** |
28 | | - * md5 crypt() password |
29 | | - * |
30 | | - * @param string $password |
31 | | - * @param string $salt |
32 | | - * |
33 | | - * @throws InvalidArgumentException if salt is emptystring |
34 | | - * @throws InvalidArgumentException if salt is longer than 8 characters |
35 | | - * @return string |
36 | | - */ |
37 | | -function md5crypt(string $pw, string $salt): string |
38 | | -{ |
39 | | - if (strlen($salt) < 1) { |
40 | | - // old implementation would crash with error "function generate_salt not defined", lets throw an exception instead |
41 | | - throw new InvalidArgumentException('salt not given!'); |
42 | | - } |
43 | | - if (strlen($salt) > 8) { |
44 | | - throw new \InvalidArgumentException("maximum supported salt length for MD5 crypt is 8 characters!"); |
45 | | - } |
46 | | - return crypt($pw, '$1$' . $salt); |
47 | | -} |
48 | | - |
49 | 29 |
|
50 | 30 | // Check arguments |
51 | | -if ((!empty($_POST['email'])) && (!empty($_POST['password'])) && (!empty($_POST['new']))) { |
52 | | - list($v_account, $v_domain) = explode('@', $_POST['email']); |
53 | | - $v_domain = escapeshellarg($v_domain); |
54 | | - $v_account = escapeshellarg($v_account); |
55 | | - $v_password = $_POST['password']; |
56 | 31 |
|
57 | | - // Get domain owner |
58 | | - exec (HESTIA_CMD."v-search-domain-owner ".$v_domain." 'mail'", $output, $return_var); |
59 | | - if ($return_var == 0) { |
60 | | - $v_user = $output[0]; |
61 | | - } |
62 | | - unset($output); |
| 32 | +if (empty($_POST['email'])) { |
| 33 | + echo "error email address not provided"; |
| 34 | + exit; |
| 35 | +} |
| 36 | +if (empty($_POST['password'])) { |
| 37 | + echo "error old password provided"; |
| 38 | + exit; |
| 39 | +} |
| 40 | +if (empty($_POST['new'])) { |
| 41 | + echo "error new password not provided"; |
| 42 | + exit; |
| 43 | +} |
63 | 44 |
|
64 | | - // Get current md5 hash |
65 | | - if (!empty($v_user)) { |
66 | | - exec (HESTIA_CMD."v-get-mail-account-value ".escapeshellarg($v_user)." ".$v_domain." ".$v_account." 'md5'", $output, $return_var); |
67 | | - if ($return_var == 0) { |
68 | | - $v_hash = $output[0]; |
69 | | - } |
70 | | - } |
71 | | - unset($output); |
| 45 | +list($v_account, $v_domain) = explode('@', $_POST['email']); |
| 46 | +$v_domain = escapeshellarg($v_domain); |
| 47 | +$v_account = escapeshellarg($v_account); |
| 48 | +$v_password = $_POST['password']; |
72 | 49 |
|
73 | | - // Compare hashes |
74 | | - if (!empty($v_hash)) { |
75 | | - $salt = explode('$', $v_hash); |
76 | | - if($salt[0] == "{MD5}"){ |
77 | | - $n_hash = md5crypt($v_password, $salt[2]); |
78 | | - $n_hash = '{MD5}'.$n_hash; |
79 | | - }else{ |
80 | | - $v_password = escapeshellarg($v_password); |
81 | | - $s_hash = escapeshellarg($v_hash); |
82 | | - exec(HESTIA_CMD."v-check-mail-account-hash ARGONID2 ". $v_password ." ". $s_hash, $output, $return_var); |
83 | | - if($return_var != 0){ |
84 | | - $n_hash = ''; |
85 | | - }else{ |
86 | | - $n_hash = $v_hash; |
87 | | - } |
88 | | - } |
89 | | - // Change password |
90 | | - if ( $v_hash == $n_hash ) { |
91 | | - $v_new_password = tempnam("/tmp","vst"); |
92 | | - $fp = fopen($v_new_password, "w"); |
93 | | - fwrite($fp, $_POST['new']."\n"); |
94 | | - fclose($fp); |
95 | | - exec (HESTIA_CMD."v-change-mail-account-password ".escapeshellarg($v_user)." ".$v_domain." ".$v_account." ".$v_new_password, $output, $return_var); |
96 | | - if ($return_var == 0) { |
97 | | - echo "==ok=="; |
98 | | - exit; |
99 | | - } |
100 | | - } |
101 | | - } |
| 50 | +// Get domain owner |
| 51 | +exec(HESTIA_CMD . "v-search-domain-owner " . $v_domain . " 'mail'", $output, $return_var); |
| 52 | +if ($return_var != 0 || empty($output[0])) { |
| 53 | + echo "error domain owner not found"; |
| 54 | + exit; |
102 | 55 | } |
| 56 | +$v_user = $output[0]; |
| 57 | +unset($output); |
103 | 58 |
|
104 | | -echo 'error'; |
105 | 59 |
|
| 60 | +// Get current password hash (called "md5" for legacy reasons, it's not guaranteed to be md5) |
| 61 | +exec(HESTIA_CMD . "v-get-mail-account-value " . escapeshellarg($v_user) . " " . $v_domain . " " . $v_account . " 'md5'", $output, $return_var); |
| 62 | +if ($return_var != 0 || empty($output[0])) { |
| 63 | + echo "error unable to get current account password hash"; |
| 64 | + exit; |
| 65 | +} |
| 66 | +$v_hash = $output[0]; |
| 67 | +unset($output); |
| 68 | + |
| 69 | +// v_hash use doveadm password hash format, which is basically {HASH_NAME}normal_crypt_format, |
| 70 | +// so we just need to remove the {HASH_NAME} before we can ask password_verify if its correct or not. |
| 71 | +$hash_for_password_verify = explode('}', $v_hash, 2); |
| 72 | +$hash_for_password_verify = end($hash_for_password_verify); |
| 73 | +if (!password_verify($v_password, $hash_for_password_verify)) { |
| 74 | + die("error old password does not match"); |
| 75 | +} |
| 76 | + |
| 77 | +// Change password |
| 78 | +$fp = tmpfile(); |
| 79 | +$new_password_file = stream_get_meta_data($fp)['uri']; |
| 80 | +fwrite($fp, $_POST['new'] . "\n"); |
| 81 | +exec(HESTIA_CMD . "v-change-mail-account-password " . escapeshellarg($v_user) . " " . $v_domain . " " . $v_account . " " . escapeshellarg($new_password_file), $output, $return_var); |
| 82 | +fclose($fp); |
| 83 | +if ($return_var == 0) { |
| 84 | + echo "==ok=="; |
| 85 | + exit; |
| 86 | +} |
| 87 | +echo 'error v-change-mail-account-password returned non-zero: ' . $return_var; |
106 | 88 | exit; |
0 commit comments