index.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <?php
  2. define('HESTIA_CMD', '/usr/bin/sudo /usr/local/hestia/bin/');
  3. //die("Error: Disabled");
  4. function check_local_ip($addr){
  5. if(in_array($addr, array($_SERVER['SERVER_ADDR'], '127.0.0.1'))){
  6. return true;
  7. }else{
  8. return false;
  9. }
  10. }
  11. function get_real_user_ip(){
  12. $ip = $_SERVER['REMOTE_ADDR'];
  13. if(isset($_SERVER['HTTP_CLIENT_IP']) && !check_local_ip($_SERVER['HTTP_CLIENT_IP'])) {
  14. if (filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP)){
  15. $ip = $_SERVER['HTTP_CLIENT_IP'];
  16. }
  17. }
  18. if(isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !check_local_ip($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  19. if (filter_var($_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP)){
  20. $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
  21. }
  22. }
  23. if(isset($_SERVER['HTTP_FORWARDED_FOR']) && !check_local_ip($_SERVER['HTTP_FORWARDED_FOR'])) {
  24. if (filter_var($_SERVER['HTTP_FORWARDED_FOR'], FILTER_VALIDATE_IP)){
  25. $ip = $_SERVER['HTTP_FORWARDED_FOR'];
  26. }
  27. }
  28. if(isset($_SERVER['HTTP_X_FORWARDED']) && !check_local_ip($_SERVER['HTTP_X_FORWARDED'])) {
  29. if (filter_var($_SERVER['HTTP_X_FORWARDED'], FILTER_VALIDATE_IP)){
  30. $ip = $_SERVER['HTTP_X_FORWARDED'];
  31. }
  32. }
  33. if(isset($_SERVER['HTTP_FORWARDED']) && !check_local_ip($_SERVER['HTTP_FORWARDED'])) {
  34. if (filter_var($_SERVER['HTTP_FORWARDED'], FILTER_VALIDATE_IP)){
  35. $ip = $_SERVER['HTTP_FORWARDED'];
  36. }
  37. }
  38. if(isset($_SERVER['HTTP_CF_CONNECTING_IP']) && !check_local_ip($_SERVER['HTTP_CF_CONNECTING_IP'])) {
  39. if (filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP)){
  40. $ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
  41. }
  42. }
  43. return $ip;
  44. }
  45. function api($hst_hash, $hst_user, $hst_password, $hst_returncode, $hst_cmd, $hst_arg1, $hst_arg2, $hst_arg3, $hst_arg4, $hst_arg5, $hst_arg6, $hst_arg7, $hst_arg8, $hst_arg9){
  46. exec (HESTIA_CMD."v-list-sys-config json" , $output, $return_var);
  47. $settings = json_decode(implode('', $output), true);
  48. unset($output);
  49. if( $settings['config']['API'] != 'yes' ){
  50. echo 'Error: API has been disabled';
  51. exit;
  52. }
  53. if ( $settings['config']['API_ALLOWED_IP'] != 'allow-all' ){
  54. $ip_list = explode(',',$settings['config']['API_ALLOWED_IP']);
  55. $ip_list[] = '';
  56. if ( !in_array(get_real_user_ip(), $ip_list)){
  57. echo 'Error: IP is not allowed to connect with API';
  58. exit;
  59. }
  60. }
  61. //This exists, so native JSON can be used without the repeating the code twice, so future code changes are easier and don't need to be replicated twice
  62. // Authentication
  63. if (empty($hst_hash)) {
  64. if ($hst_user != 'admin') {
  65. echo 'Error: authentication failed';
  66. exit;
  67. }
  68. $password = $hst_password;
  69. if (!isset($password)){
  70. echo 'Error: missing authentication';
  71. exit;
  72. }
  73. $v_ip = escapeshellarg(get_real_user_ip());
  74. $output = '';
  75. exec (HESTIA_CMD."v-get-user-salt admin ".$v_ip." json" , $output, $return_var);
  76. $pam = json_decode(implode('', $output), true);
  77. $salt = $pam['admin']['SALT'];
  78. $method = $pam['admin']['METHOD'];
  79. if ($method == 'md5' ) {
  80. $hash = crypt($password, '$1$'.$salt.'$');
  81. }
  82. if ($method == 'sha-512' ) {
  83. $hash = crypt($password, '$6$rounds=5000$'.$salt.'$');
  84. $hash = str_replace('$rounds=5000','',$hash);
  85. }
  86. if ($method == 'des' ) {
  87. $hash = crypt($password, $salt);
  88. }
  89. // Send hash via tmp file
  90. $v_hash = exec('mktemp -p /tmp');
  91. $fp = fopen($v_hash, "w");
  92. fwrite($fp, $hash."\n");
  93. fclose($fp);
  94. // Check user hash
  95. exec(HESTIA_CMD ."v-check-user-hash admin ".$v_hash." ".$v_ip, $output, $return_var);
  96. unset($output);
  97. // Remove tmp file
  98. unlink($v_hash);
  99. // Check API answer
  100. if ( $return_var > 0 ) {
  101. echo 'Error: authentication failed';
  102. exit;
  103. }
  104. } else {
  105. $key = '/usr/local/hestia/data/keys/' . basename($hst_hash);
  106. $v_ip = escapeshellarg(get_real_user_ip());
  107. exec(HESTIA_CMD ."v-check-api-key ".escapeshellarg($key)." ".$v_ip, $output, $return_var);
  108. unset($output);
  109. // Check API answer
  110. if ( $return_var > 0 ) {
  111. echo 'Error: authentication failed';
  112. exit;
  113. }
  114. }
  115. // Prepare arguments
  116. if (isset($hst_cmd)) $cmd = escapeshellarg($hst_cmd);
  117. if (isset($hst_arg1)) $arg1 = escapeshellarg($hst_arg1);
  118. if (isset($hst_arg2)) $arg2 = escapeshellarg($hst_arg2);
  119. if (isset($hst_arg3)) $arg3 = escapeshellarg($hst_arg3);
  120. if (isset($hst_arg4)) $arg4 = escapeshellarg($hst_arg4);
  121. if (isset($hst_arg5)) $arg5 = escapeshellarg($hst_arg5);
  122. if (isset($hst_arg6)) $arg6 = escapeshellarg($hst_arg6);
  123. if (isset($hst_arg7)) $arg7 = escapeshellarg($hst_arg7);
  124. if (isset($hst_arg8)) $arg8 = escapeshellarg($hst_arg8);
  125. if (isset($hst_arg9)) $arg9 = escapeshellarg($hst_arg9);
  126. // Build query
  127. $cmdquery = HESTIA_CMD.$cmd." ";
  128. if(!empty($arg1)){
  129. $cmdquery = $cmdquery.$arg1." "; }
  130. if(!empty($arg2)){
  131. $cmdquery = $cmdquery.$arg2." "; }
  132. if(!empty($arg3)){
  133. $cmdquery = $cmdquery.$arg3." "; }
  134. if(!empty($arg4)){
  135. $cmdquery = $cmdquery.$arg4." "; }
  136. if(!empty($arg5)){
  137. $cmdquery = $cmdquery.$arg5." "; }
  138. if(!empty($arg6)){
  139. $cmdquery = $cmdquery.$arg6." "; }
  140. if(!empty($arg7)){
  141. $cmdquery = $cmdquery.$arg7." "; }
  142. if(!empty($arg8)){
  143. $cmdquery = $cmdquery.$arg8." "; }
  144. if(!empty($arg9)){
  145. $cmdquery = $cmdquery.$arg9; }
  146. // Check command
  147. if ($cmd == "'v-make-tmp-file'") {
  148. // Used in DNS Cluster
  149. $fp = fopen('/tmp/'.basename($hst_arg2), 'w');
  150. fwrite($fp, $hst_arg1."\n");
  151. fclose($fp);
  152. $return_var = 0;
  153. } else {
  154. // Run normal cmd query
  155. exec ($cmdquery, $output, $return_var);
  156. }
  157. if ((!empty($hst_returncode)) && ($hst_returncode == 'yes')) {
  158. echo $return_var;
  159. } else {
  160. if (($return_var == 0) && (empty($output))) {
  161. echo "OK";
  162. } else {
  163. echo implode("\n",$output)."\n";
  164. }
  165. }
  166. }
  167. if (isset($_POST['user']) || isset($_POST['hash'])) {
  168. api($_POST['hash'], $_POST['user'], $_POST['password'], $_POST['returncode'], $_POST['cmd'], $_POST['arg1'], $_POST['arg2'], $_POST['arg3'], $_POST['arg4'], $_POST['arg5'], $_POST['arg6'], $_POST['arg7'], $_POST['arg8'], $_POST['arg9']);
  169. } else if (json_decode(file_get_contents("php://input"), true) != NULL){ //JSON POST support
  170. $json_data = json_decode(file_get_contents("php://input"), true);
  171. api($json_data['hash'], $json_data['user'], $json_data['password'], $json_data['returncode'], $json_data['cmd'], $json_data['arg1'], $json_data['arg2'], $json_data['arg3'], $json_data['arg4'], $json_data['arg5'], $json_data['arg6'], $json_data['arg7'], $json_data['arg8'], $json_data['arg9']);
  172. } else {
  173. echo "Error: data received is null or invalid, check https://docs.hestiacp.com/admin_docs/api.html";
  174. exit;
  175. }
  176. ?>