"Fossies" - the Fresh Open Source Software Archive

Member "phpMyAdmin-5.1.0-all-languages/libraries/classes/Plugins/Auth/AuthenticationSignon.php" (24 Feb 2021, 9265 Bytes) of package /linux/www/phpMyAdmin-5.1.0-all-languages.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "AuthenticationSignon.php": 5.0.4-english_vs_5.1.0-english.

    1 <?php
    2 /**
    3  * SignOn Authentication plugin for phpMyAdmin
    4  */
    5 
    6 declare(strict_types=1);
    7 
    8 namespace PhpMyAdmin\Plugins\Auth;
    9 
   10 use PhpMyAdmin\Core;
   11 use PhpMyAdmin\Plugins\AuthenticationPlugin;
   12 use PhpMyAdmin\Util;
   13 use const PHP_VERSION;
   14 use function array_merge;
   15 use function defined;
   16 use function file_exists;
   17 use function in_array;
   18 use function session_get_cookie_params;
   19 use function session_id;
   20 use function session_name;
   21 use function session_set_cookie_params;
   22 use function session_start;
   23 use function session_write_close;
   24 use function version_compare;
   25 
   26 /**
   27  * Handles the SignOn authentication method
   28  */
   29 class AuthenticationSignon extends AuthenticationPlugin
   30 {
   31     /**
   32      * Displays authentication form
   33      *
   34      * @return bool always true (no return indeed)
   35      */
   36     public function showLoginForm()
   37     {
   38         unset($_SESSION['LAST_SIGNON_URL']);
   39         if (empty($GLOBALS['cfg']['Server']['SignonURL'])) {
   40             Core::fatalError('You must set SignonURL!');
   41         } else {
   42             Core::sendHeaderLocation($GLOBALS['cfg']['Server']['SignonURL']);
   43         }
   44 
   45         if (! defined('TESTSUITE')) {
   46             exit;
   47         }
   48 
   49         return false;
   50     }
   51 
   52     /**
   53      * Set cookie params
   54      *
   55      * @param array $sessionCookieParams The cookie params
   56      */
   57     public function setCookieParams(?array $sessionCookieParams = null): void
   58     {
   59         /* Session cookie params from config */
   60         if ($sessionCookieParams === null) {
   61             $sessionCookieParams = (array) $GLOBALS['cfg']['Server']['SignonCookieParams'];
   62         }
   63 
   64         /* Sanitize cookie params */
   65         $defaultCookieParams = static function (string $key) {
   66             switch ($key) {
   67                 case 'lifetime':
   68                     return 0;
   69                 case 'path':
   70                     return '/';
   71                 case 'domain':
   72                     return '';
   73                 case 'secure':
   74                     return false;
   75                 case 'httponly':
   76                     return false;
   77             }
   78 
   79             return null;
   80         };
   81 
   82         foreach (['lifetime', 'path', 'domain', 'secure', 'httponly'] as $key) {
   83             if (isset($sessionCookieParams[$key])) {
   84                 continue;
   85             }
   86 
   87             $sessionCookieParams[$key] = $defaultCookieParams($key);
   88         }
   89 
   90         if (isset($sessionCookieParams['samesite'])
   91             && ! in_array($sessionCookieParams['samesite'], ['Lax', 'Strict'])
   92         ) {
   93                 // Not a valid value for samesite
   94                 unset($sessionCookieParams['samesite']);
   95         }
   96 
   97         if (version_compare(PHP_VERSION, '7.3.0', '>=')) {
   98             session_set_cookie_params($sessionCookieParams);
   99         } else {
  100             session_set_cookie_params(
  101                 $sessionCookieParams['lifetime'],
  102                 $sessionCookieParams['path'],
  103                 $sessionCookieParams['domain'],
  104                 $sessionCookieParams['secure'],
  105                 $sessionCookieParams['httponly']
  106             );
  107         }
  108     }
  109 
  110     /**
  111      * Gets authentication credentials
  112      *
  113      * @return bool whether we get authentication settings or not
  114      */
  115     public function readCredentials()
  116     {
  117         /* Check if we're using same signon server */
  118         $signon_url = $GLOBALS['cfg']['Server']['SignonURL'];
  119         if (isset($_SESSION['LAST_SIGNON_URL'])
  120             && $_SESSION['LAST_SIGNON_URL'] != $signon_url
  121         ) {
  122             return false;
  123         }
  124 
  125         /* Script name */
  126         $script_name = $GLOBALS['cfg']['Server']['SignonScript'];
  127 
  128         /* Session name */
  129         $session_name = $GLOBALS['cfg']['Server']['SignonSession'];
  130 
  131         /* Login URL */
  132         $signon_url = $GLOBALS['cfg']['Server']['SignonURL'];
  133 
  134         /* Current host */
  135         $single_signon_host = $GLOBALS['cfg']['Server']['host'];
  136 
  137         /* Current port */
  138         $single_signon_port = $GLOBALS['cfg']['Server']['port'];
  139 
  140         /* No configuration updates */
  141         $single_signon_cfgupdate = [];
  142 
  143         /* Handle script based auth */
  144         if (! empty($script_name)) {
  145             if (! @file_exists($script_name)) {
  146                 Core::fatalError(
  147                     __('Can not find signon authentication script:')
  148                     . ' ' . $script_name
  149                 );
  150             }
  151             include $script_name;
  152 
  153             [$this->user, $this->password]
  154                 = get_login_credentials($GLOBALS['cfg']['Server']['user']);
  155         } elseif (isset($_COOKIE[$session_name])) { /* Does session exist? */
  156             /* End current session */
  157             $old_session = session_name();
  158             $old_id = session_id();
  159             $oldCookieParams = session_get_cookie_params();
  160             if (! defined('TESTSUITE')) {
  161                 session_write_close();
  162             }
  163             /* Load single signon session */
  164             if (! defined('TESTSUITE')) {
  165                 $this->setCookieParams();
  166                 session_name($session_name);
  167                 session_id($_COOKIE[$session_name]);
  168                 session_start();
  169             }
  170 
  171             /* Clear error message */
  172             unset($_SESSION['PMA_single_signon_error_message']);
  173 
  174             /* Grab credentials if they exist */
  175             if (isset($_SESSION['PMA_single_signon_user'])) {
  176                 $this->user = $_SESSION['PMA_single_signon_user'];
  177             }
  178             if (isset($_SESSION['PMA_single_signon_password'])) {
  179                 $this->password = $_SESSION['PMA_single_signon_password'];
  180             }
  181             if (isset($_SESSION['PMA_single_signon_host'])) {
  182                 $single_signon_host = $_SESSION['PMA_single_signon_host'];
  183             }
  184 
  185             if (isset($_SESSION['PMA_single_signon_port'])) {
  186                 $single_signon_port = $_SESSION['PMA_single_signon_port'];
  187             }
  188 
  189             if (isset($_SESSION['PMA_single_signon_cfgupdate'])) {
  190                 $single_signon_cfgupdate = $_SESSION['PMA_single_signon_cfgupdate'];
  191             }
  192 
  193             /* Also get token as it is needed to access subpages */
  194             if (isset($_SESSION['PMA_single_signon_token'])) {
  195                 /* No need to care about token on logout */
  196                 $pma_token = $_SESSION['PMA_single_signon_token'];
  197             }
  198 
  199             $HMACSecret = Util::generateRandom(16);
  200             if (isset($_SESSION['PMA_single_signon_HMAC_secret'])) {
  201                 $HMACSecret = $_SESSION['PMA_single_signon_HMAC_secret'];
  202             }
  203 
  204             /* End single signon session */
  205             if (! defined('TESTSUITE')) {
  206                 session_write_close();
  207             }
  208 
  209             /* Restart phpMyAdmin session */
  210             if (! defined('TESTSUITE')) {
  211                 $this->setCookieParams($oldCookieParams);
  212                 if ($old_session !== null) {
  213                     session_name($old_session);
  214                 }
  215                 if (! empty($old_id)) {
  216                     session_id($old_id);
  217                 }
  218                 session_start();
  219             }
  220 
  221             /* Set the single signon host */
  222             $GLOBALS['cfg']['Server']['host'] = $single_signon_host;
  223 
  224             /* Set the single signon port */
  225             $GLOBALS['cfg']['Server']['port'] = $single_signon_port;
  226 
  227             /* Configuration update */
  228             $GLOBALS['cfg']['Server'] = array_merge(
  229                 $GLOBALS['cfg']['Server'],
  230                 $single_signon_cfgupdate
  231             );
  232 
  233             /* Restore our token */
  234             if (! empty($pma_token)) {
  235                 $_SESSION[' PMA_token '] = $pma_token;
  236                 $_SESSION[' HMAC_secret '] = $HMACSecret;
  237             }
  238 
  239             /**
  240              * Clear user cache.
  241              */
  242             Util::clearUserCache();
  243         }
  244 
  245         // Returns whether we get authentication settings or not
  246         if (empty($this->user)) {
  247             unset($_SESSION['LAST_SIGNON_URL']);
  248 
  249             return false;
  250         }
  251 
  252         $_SESSION['LAST_SIGNON_URL'] = $GLOBALS['cfg']['Server']['SignonURL'];
  253 
  254         return true;
  255     }
  256 
  257     /**
  258      * User is not allowed to login to MySQL -> authentication failed
  259      *
  260      * @param string $failure String describing why authentication has failed
  261      *
  262      * @return void
  263      */
  264     public function showFailure($failure)
  265     {
  266         parent::showFailure($failure);
  267 
  268         /* Session name */
  269         $session_name = $GLOBALS['cfg']['Server']['SignonSession'];
  270 
  271         /* Does session exist? */
  272         if (isset($_COOKIE[$session_name])) {
  273             if (! defined('TESTSUITE')) {
  274                 /* End current session */
  275                 session_write_close();
  276 
  277                 /* Load single signon session */
  278                 $this->setCookieParams();
  279                 session_name($session_name);
  280                 session_id($_COOKIE[$session_name]);
  281                 session_start();
  282             }
  283 
  284             /* Set error message */
  285             $_SESSION['PMA_single_signon_error_message'] = $this->getErrorMessage($failure);
  286         }
  287         $this->showLoginForm();
  288     }
  289 
  290     /**
  291      * Returns URL for login form.
  292      *
  293      * @return string
  294      */
  295     public function getLoginFormURL()
  296     {
  297         return $GLOBALS['cfg']['Server']['SignonURL'];
  298     }
  299 }