hestia-sso.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <?php
  2. /* Hestia way to enable support for SSO to PHPmyAdmin */
  3. /* To install please run v-add-sys-pma-sso */
  4. /* Following keys will get replaced when calling v-add-sys-pma-sso */
  5. define('PHPMYADMIN_KEY','%PHPMYADMIN_KEY%');
  6. define('API_HOST_NAME','%API_HOST_NAME%');
  7. define('API_HESTIA_PORT','%API_HESTIA_PORT%');
  8. define('API_KEY', '%API_KEY%');
  9. class Hestia_API {
  10. private $api_url;
  11. function __construct(){
  12. $this -> hostname = 'https://' . API_HOST_NAME . ':' . API_HESTIA_PORT .'/api/';
  13. $this -> key = API_KEY;
  14. $this -> pma_key = PHPMYADMIN_KEY;
  15. }
  16. /* Creates curl request */
  17. function request($postvars){
  18. $postdata = http_build_query($postvars);
  19. $curl = curl_init();
  20. curl_setopt($curl, CURLOPT_URL, $this -> hostname);
  21. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  22. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  23. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
  24. curl_setopt($curl, CURLOPT_POST, true);
  25. curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
  26. $answer = curl_exec($curl);
  27. return $answer;
  28. }
  29. /* Creates an new temp user in mysql */
  30. function create_temp_user ($database, $user, $host){
  31. $post_request = array(
  32. 'hash' => $this -> key,
  33. 'returncode' => 'no',
  34. 'cmd' => 'v-add-database-temp-user',
  35. 'arg1' => $user,
  36. 'arg2' => $database,
  37. 'arg3' => 'mysql',
  38. 'arg4' => $host
  39. );
  40. $request = $this -> request($post_request);
  41. $json = json_decode($request);
  42. if(json_last_error() == JSON_ERROR_NONE){
  43. return $json;
  44. }else{
  45. return false;
  46. }
  47. }
  48. /* Delete an new temp user in mysql */
  49. function delete_temp_user ($database, $user, $dbuser, $host){
  50. $post_request = array(
  51. 'hash' => $this -> key,
  52. 'returncode' => 'yes',
  53. 'cmd' => 'v-delete-database-temp-user',
  54. 'arg1' => $user,
  55. 'arg2' => $database,
  56. 'arg3' => $dbuser,
  57. 'arg4' => 'mysql',
  58. 'arg5' => $host
  59. );
  60. $request = $this -> request($post_request);
  61. if(is_numeric($request) && $request == 0){
  62. return true;
  63. }else{
  64. return false;
  65. }
  66. }
  67. function get_user_ip(){
  68. // Saving user IPs to the session for preventing session hijacking
  69. $user_combined_ip = $_SERVER['REMOTE_ADDR'];
  70. if(isset($_SERVER['HTTP_CLIENT_IP'])){
  71. $user_combined_ip .= '|'. $_SERVER['HTTP_CLIENT_IP'];
  72. }
  73. if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
  74. if($_SERVER['REMOTE_ADDR'] != $_SERVER['HTTP_X_FORWARDED_FOR']){
  75. $user_combined_ip .= '|'. $_SERVER['HTTP_X_FORWARDED_FOR'];
  76. }
  77. }
  78. if(isset($_SERVER['HTTP_FORWARDED_FOR'])){
  79. if($_SERVER['REMOTE_ADDR'] != $_SERVER['HTTP_FORWARDED_FOR']){
  80. $user_combined_ip .= '|'. $_SERVER['HTTP_FORWARDED_FOR'];
  81. }
  82. }
  83. if(isset($_SERVER['HTTP_X_FORWARDED'])){
  84. if($_SERVER['REMOTE_ADDR'] != $_SERVER['HTTP_X_FORWARDED']){
  85. $user_combined_ip .= '|'. $_SERVER['HTTP_X_FORWARDED'];
  86. }
  87. } if(isset($_SERVER['HTTP_FORWARDED'])){
  88. if($_SERVER['REMOTE_ADDR'] != $_SERVER['HTTP_FORWARDED']){
  89. $user_combined_ip .= '|'. $_SERVER['HTTP_FORWARDED'];
  90. }
  91. }
  92. if(isset($_SERVER['HTTP_CF_CONNECTING_IP'])){
  93. if(!empty($_SERVER['HTTP_CF_CONNECTING_IP'])){
  94. $user_combined_ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
  95. }
  96. }
  97. return $user_combined_ip;
  98. }
  99. }
  100. /* Need to have cookie visible from parent directory */
  101. session_set_cookie_params(0, '/', '', true, true);
  102. /* Create signon session */
  103. $session_name = 'SignonSession';
  104. session_name($session_name);
  105. @session_start();
  106. function session_invalid(){
  107. global $session_name;
  108. //delete all current sessions
  109. session_destroy();
  110. setcookie($session_name, null, -1, '/');
  111. header('Location: /phpmyadmin/index.php');
  112. die();
  113. }
  114. $api = new Hestia_API();
  115. if(!empty($_GET)){
  116. if(isset($_GET['logout'])){
  117. $api -> delete_temp_user($_SESSION['HESTIA_sso_database'], $_SESSION['HESTIA_sso_user'], $_SESSION['PMA_single_signon_user'], $_SESSION['HESTIA_sso_host']);
  118. //remove sessin
  119. session_invalid();
  120. }else{
  121. if(isset($_GET['user']) && isset($_GET['hestia_token'])){
  122. $database = $_GET['database'];
  123. $user = $_GET['user'];
  124. $host = 'localhost';
  125. $token = $_GET['hestia_token'];
  126. $time = $_GET['exp'];
  127. if($time + 60 > time()){
  128. //note: Possible issues with cloudflare due to ip obfuscation
  129. $ip = $api -> get_user_ip();
  130. if(!password_verify($database.$user.$ip.$time.PHPMYADMIN_KEY,$token)){
  131. session_invalid();
  132. }else{
  133. $id = session_id();
  134. //create a new temp user
  135. $data = $api -> create_temp_user($database,$user, $host);
  136. $_SESSION['PMA_single_signon_user'] = $data -> login -> user;
  137. $_SESSION['PMA_single_signon_password'] = $data -> login -> password ;
  138. $_SESSION['PMA_single_signon_host'] = $host;
  139. //save database / username to be used for sending logout notification.
  140. $_SESSION['HESTIA_sso_user'] = $user;
  141. $_SESSION['HESTIA_sso_database'] = $database;
  142. $_SESSION['HESTIA_sso_host'] = $host;
  143. @session_write_close();
  144. setcookie($session_name, $id , 0, "/");
  145. header('Location: /phpmyadmin/index.php');
  146. die();
  147. }
  148. }else{
  149. session_invalid();
  150. }
  151. }
  152. }
  153. }else{
  154. session_invalid();
  155. }
  156. ?>