AuthenticationSignon.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * SignOn Authentication plugin for phpMyAdmin
  5. *
  6. * @package PhpMyAdmin-Authentication
  7. * @subpackage SignOn
  8. */
  9. namespace PhpMyAdmin\Plugins\Auth;
  10. use PhpMyAdmin\Core;
  11. use PhpMyAdmin\Plugins\AuthenticationPlugin;
  12. use PhpMyAdmin\Util;
  13. /**
  14. * Handles the SignOn authentication method
  15. *
  16. * @package PhpMyAdmin-Authentication
  17. */
  18. class AuthenticationSignon extends AuthenticationPlugin
  19. {
  20. /**
  21. * Displays authentication form
  22. *
  23. * @return boolean always true (no return indeed)
  24. */
  25. public function showLoginForm()
  26. {
  27. unset($_SESSION['LAST_SIGNON_URL']);
  28. if (empty($GLOBALS['cfg']['Server']['SignonURL'])) {
  29. Core::fatalError('You must set SignonURL!');
  30. } else {
  31. Core::sendHeaderLocation($GLOBALS['cfg']['Server']['SignonURL']);
  32. }
  33. if (!defined('TESTSUITE')) {
  34. exit();
  35. } else {
  36. return false;
  37. }
  38. }
  39. /**
  40. * Gets authentication credentials
  41. *
  42. * @return boolean whether we get authentication settings or not
  43. */
  44. public function readCredentials()
  45. {
  46. /* Check if we're using same signon server */
  47. $signon_url = $GLOBALS['cfg']['Server']['SignonURL'];
  48. if (isset($_SESSION['LAST_SIGNON_URL'])
  49. && $_SESSION['LAST_SIGNON_URL'] != $signon_url
  50. ) {
  51. return false;
  52. }
  53. /* Script name */
  54. $script_name = $GLOBALS['cfg']['Server']['SignonScript'];
  55. /* Session name */
  56. $session_name = $GLOBALS['cfg']['Server']['SignonSession'];
  57. /* Session cookie params */
  58. $session_cookie_params = (array) $GLOBALS['cfg']['Server']['SignonCookieParams'];
  59. /* Login URL */
  60. $signon_url = $GLOBALS['cfg']['Server']['SignonURL'];
  61. /* Current host */
  62. $single_signon_host = $GLOBALS['cfg']['Server']['host'];
  63. /* Current port */
  64. $single_signon_port = $GLOBALS['cfg']['Server']['port'];
  65. /* No configuration updates */
  66. $single_signon_cfgupdate = array();
  67. /* Handle script based auth */
  68. if (!empty($script_name)) {
  69. if (!@file_exists($script_name)) {
  70. Core::fatalError(
  71. __('Can not find signon authentication script:')
  72. . ' ' . $script_name
  73. );
  74. }
  75. include $script_name;
  76. list ($this->user, $this->password)
  77. = get_login_credentials($GLOBALS['cfg']['Server']['user']);
  78. } elseif (isset($_COOKIE[$session_name])) { /* Does session exist? */
  79. /* End current session */
  80. $old_session = session_name();
  81. $old_id = session_id();
  82. $old_cookie_params = session_get_cookie_params();
  83. if (!defined('TESTSUITE')) {
  84. session_write_close();
  85. }
  86. /* Sanitize cookie params */
  87. $defaultCookieParams = function($key){
  88. switch ($key) {
  89. case 'lifetime': return 0;
  90. case 'path': return '/';
  91. case 'domain': return '';
  92. case 'secure': return false;
  93. case 'httponly': return false;
  94. }
  95. return null;
  96. };
  97. foreach (array('lifetime', 'path', 'domain', 'secure', 'httponly') as $key) {
  98. if (!isset($session_cookie_params[$key]))
  99. $session_cookie_params[$key] = $defaultCookieParams($key);
  100. }
  101. /* Load single signon session */
  102. if (!defined('TESTSUITE')) {
  103. session_set_cookie_params($session_cookie_params['lifetime'], $session_cookie_params['path'], $session_cookie_params['domain'], $session_cookie_params['secure'], $session_cookie_params['httponly']);
  104. session_name($session_name);
  105. session_id($_COOKIE[$session_name]);
  106. session_start();
  107. }
  108. /* Clear error message */
  109. unset($_SESSION['PMA_single_signon_error_message']);
  110. /* Grab credentials if they exist */
  111. if (isset($_SESSION['PMA_single_signon_user'])) {
  112. $this->user = $_SESSION['PMA_single_signon_user'];
  113. }
  114. if (isset($_SESSION['PMA_single_signon_password'])) {
  115. $this->password = $_SESSION['PMA_single_signon_password'];
  116. }
  117. if (isset($_SESSION['PMA_single_signon_host'])) {
  118. $single_signon_host = $_SESSION['PMA_single_signon_host'];
  119. }
  120. if (isset($_SESSION['PMA_single_signon_port'])) {
  121. $single_signon_port = $_SESSION['PMA_single_signon_port'];
  122. }
  123. if (isset($_SESSION['PMA_single_signon_cfgupdate'])) {
  124. $single_signon_cfgupdate = $_SESSION['PMA_single_signon_cfgupdate'];
  125. }
  126. /* Also get token as it is needed to access subpages */
  127. if (isset($_SESSION['PMA_single_signon_token'])) {
  128. /* No need to care about token on logout */
  129. $pma_token = $_SESSION['PMA_single_signon_token'];
  130. }
  131. /* End single signon session */
  132. if (!defined('TESTSUITE')) {
  133. session_write_close();
  134. }
  135. /* Restart phpMyAdmin session */
  136. if (!defined('TESTSUITE')) {
  137. session_set_cookie_params($old_cookie_params['lifetime'], $old_cookie_params['path'], $old_cookie_params['domain'], $old_cookie_params['secure'], $old_cookie_params['httponly']);
  138. session_name($old_session);
  139. if (!empty($old_id)) {
  140. session_id($old_id);
  141. }
  142. session_start();
  143. }
  144. /* Set the single signon host */
  145. $GLOBALS['cfg']['Server']['host'] = $single_signon_host;
  146. /* Set the single signon port */
  147. $GLOBALS['cfg']['Server']['port'] = $single_signon_port;
  148. /* Configuration update */
  149. $GLOBALS['cfg']['Server'] = array_merge(
  150. $GLOBALS['cfg']['Server'],
  151. $single_signon_cfgupdate
  152. );
  153. /* Restore our token */
  154. if (!empty($pma_token)) {
  155. $_SESSION[' PMA_token '] = $pma_token;
  156. }
  157. /**
  158. * Clear user cache.
  159. */
  160. Util::clearUserCache();
  161. }
  162. // Returns whether we get authentication settings or not
  163. if (empty($this->user)) {
  164. unset($_SESSION['LAST_SIGNON_URL']);
  165. return false;
  166. }
  167. $_SESSION['LAST_SIGNON_URL'] = $GLOBALS['cfg']['Server']['SignonURL'];
  168. return true;
  169. }
  170. /**
  171. * User is not allowed to login to MySQL -> authentication failed
  172. *
  173. * @param string $failure String describing why authentication has failed
  174. *
  175. * @return void
  176. */
  177. public function showFailure($failure)
  178. {
  179. parent::showFailure($failure);
  180. /* Session name */
  181. $session_name = $GLOBALS['cfg']['Server']['SignonSession'];
  182. /* Does session exist? */
  183. if (isset($_COOKIE[$session_name])) {
  184. if (!defined('TESTSUITE')) {
  185. /* End current session */
  186. session_write_close();
  187. /* Load single signon session */
  188. session_name($session_name);
  189. session_id($_COOKIE[$session_name]);
  190. session_start();
  191. }
  192. /* Set error message */
  193. $_SESSION['PMA_single_signon_error_message'] = $this->getErrorMessage($failure);
  194. }
  195. $this->showLoginForm();
  196. }
  197. /**
  198. * Returns URL for login form.
  199. *
  200. * @return string
  201. */
  202. public function getLoginFormURL()
  203. {
  204. return $GLOBALS['cfg']['Server']['SignonURL'];
  205. }
  206. }