Fix for the Open in New Window in Patient/Client->Patients search gui, take 2.
[openemr.git] / phpmyadmin / libraries / auth / cookie.auth.lib.php
blob45e8e8d9e67efa36015ca36d4c72134cf4949008
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Set of functions used to run cookie based authentication.
5 * Thanks to Piotr Roszatycki <d3xter at users.sourceforge.net> and
6 * Dan Wilson who built this patch for the Debian package.
8 * @version $Id$
9 */
11 if (! defined('PHPMYADMIN')) {
12 exit;
15 if (function_exists('mcrypt_encrypt') || PMA_dl('mcrypt')) {
16 /**
17 * Uses faster mcrypt library if available
19 require_once './libraries/mcrypt.lib.php';
20 } else {
21 require_once './libraries/blowfish.php';
22 /**
23 * display warning in main.php
25 define('PMA_WARN_FOR_MCRYPT', 1);
29 /**
30 * Displays authentication form
32 * this function MUST exit/quit the application
34 * @uses $GLOBALS['server']
35 * @uses $GLOBALS['PHP_AUTH_USER']
36 * @uses $GLOBALS['pma_auth_server']
37 * @uses $GLOBALS['text_dir']
38 * @uses $GLOBALS['pmaThemeImage']
39 * @uses $GLOBALS['charset']
40 * @uses $GLOBALS['target']
41 * @uses $GLOBALS['db']
42 * @uses $GLOBALS['table']
43 * @uses $GLOBALS['PMA_errors']
44 * @uses $GLOBALS['convcharset']
45 * @uses $GLOBALS['lang']
46 * @uses $GLOBALS['strWelcome']
47 * @uses $GLOBALS['strSecretRequired']
48 * @uses $GLOBALS['strError']
49 * @uses $GLOBALS['strLogin']
50 * @uses $GLOBALS['strLogServer']
51 * @uses $GLOBALS['strLogUsername']
52 * @uses $GLOBALS['strLogPassword']
53 * @uses $GLOBALS['strServerChoice']
54 * @uses $GLOBALS['strGo']
55 * @uses $GLOBALS['strCookiesRequired']
56 * @uses $GLOBALS['strPmaDocumentation']
57 * @uses $GLOBALS['pmaThemeImage']
58 * @uses $cfg['Servers']
59 * @uses $cfg['LoginCookieRecall']
60 * @uses $cfg['Lang']
61 * @uses $cfg['Server']
62 * @uses $cfg['ReplaceHelpImg']
63 * @uses $cfg['blowfish_secret']
64 * @uses $cfg['AllowArbitraryServer']
65 * @uses $_COOKIE
66 * @uses $_REQUEST['old_usr']
67 * @uses PMA_sendHeaderLocation()
68 * @uses PMA_select_language()
69 * @uses PMA_select_server()
70 * @uses file_exists()
71 * @uses sprintf()
72 * @uses count()
73 * @uses htmlspecialchars()
74 * @uses is_array()
75 * @global string the last connection error
77 * @access public
79 function PMA_auth()
81 global $conn_error;
83 /* Perform logout to custom URL */
84 if (! empty($_REQUEST['old_usr'])
85 && ! empty($GLOBALS['cfg']['Server']['LogoutURL'])) {
86 PMA_sendHeaderLocation($GLOBALS['cfg']['Server']['LogoutURL']);
87 exit;
90 if ($GLOBALS['cfg']['LoginCookieRecall']) {
91 $default_user = $GLOBALS['PHP_AUTH_USER'];
92 $default_server = $GLOBALS['pma_auth_server'];
93 $autocomplete = '';
94 } else {
95 $default_user = '';
96 $default_server = '';
97 // skip the IE autocomplete feature.
98 $autocomplete = ' autocomplete="off"';
101 $cell_align = ($GLOBALS['text_dir'] == 'ltr') ? 'left' : 'right';
103 // Defines the charset to be used
104 header('Content-Type: text/html; charset=' . $GLOBALS['charset']);
105 // Defines the "item" image depending on text direction
106 $item_img = $GLOBALS['pmaThemeImage'] . 'item_' . $GLOBALS['text_dir'] . '.png';
108 /* HTML header; do not show here the PMA version to improve security */
109 $page_title = 'phpMyAdmin ';
110 require './libraries/header_meta_style.inc.php';
112 <script type="text/javascript">
113 //<![CDATA[
114 // show login form in top frame
115 if (top != self) {
116 window.top.location.href=location;
118 //]]>
119 </script>
120 </head>
122 <body class="loginform">
124 <?php
125 if (file_exists('./config.header.inc.php')) {
126 require './config.header.inc.php';
130 <div class="container">
131 <a href="http://www.phpmyadmin.net" target="_blank" class="logo"><?php
132 $logo_image = $GLOBALS['pmaThemeImage'] . 'logo_right.png';
133 if (@file_exists($logo_image)) {
134 echo '<img src="' . $logo_image . '" id="imLogo" name="imLogo" alt="phpMyAdmin" border="0" />';
135 } else {
136 echo '<img name="imLogo" id="imLogo" src="' . $GLOBALS['pmaThemeImage'] . 'pma_logo.png' . '" '
137 . 'border="0" width="88" height="31" alt="phpMyAdmin" />';
139 ?></a>
140 <h1>
141 <?php
142 echo sprintf($GLOBALS['strWelcome'],
143 '<bdo dir="ltr" xml:lang="en">' . $page_title . '</bdo>');
145 </h1>
146 <?php
148 // Show error message
149 if (! empty($conn_error)) {
150 echo '<div class="error"><h1>' . $GLOBALS['strError'] . '</h1>' . "\n";
151 echo $conn_error . '</div>' . "\n";
154 // Displays the languages form
155 if (empty($GLOBALS['cfg']['Lang'])) {
156 require_once './libraries/display_select_lang.lib.php';
157 // use fieldset, don't show doc link
158 PMA_select_language(true, false);
161 // Displays the warning message and the login form
162 if (empty($GLOBALS['cfg']['blowfish_secret'])) {
164 <div class="error"><h1><?php echo $GLOBALS['strError']; ?></h1>
165 <?php echo $GLOBALS['strSecretRequired']; ?>
166 </div>
167 <?php
168 echo '</div>' . "\n";
169 if (file_exists('./config.footer.inc.php')) {
170 require './config.footer.inc.php';
172 echo '</body></html>';
173 exit;
176 <br />
177 <!-- Login form -->
178 <form method="post" action="index.php" name="login_form"<?php echo $autocomplete; ?> target="_top" class="login">
179 <fieldset>
180 <legend>
181 <?php
182 echo $GLOBALS['strLogin'];
183 // no real need to put a link to doc here, and it would reveal the
184 // version number
186 </legend>
188 <?php if ($GLOBALS['cfg']['AllowArbitraryServer']) { ?>
189 <div class="item">
190 <label for="input_servername"><?php echo $GLOBALS['strLogServer']; ?></label>
191 <input type="text" name="pma_servername" id="input_servername" value="<?php echo htmlspecialchars($default_server); ?>" size="24" class="textfield" />
192 </div>
193 <?php } ?>
194 <div class="item">
195 <label for="input_username"><?php echo $GLOBALS['strLogUsername']; ?></label>
196 <input type="text" name="pma_username" id="input_username" value="<?php echo htmlspecialchars($default_user); ?>" size="24" class="textfield" />
197 </div>
198 <div class="item">
199 <label for="input_password"><?php echo $GLOBALS['strLogPassword']; ?></label>
200 <input type="password" name="pma_password" id="input_password" value="" size="24" class="textfield" />
201 </div>
202 <?php
203 if (count($GLOBALS['cfg']['Servers']) > 1) {
205 <div class="item">
206 <label for="select_server"><?php echo $GLOBALS['strServerChoice']; ?>:</label>
207 <select name="server" id="select_server"
208 <?php
209 if ($GLOBALS['cfg']['AllowArbitraryServer']) {
210 echo ' onchange="document.forms[\'login_form\'].elements[\'pma_servername\'].value = \'\'" ';
212 echo '>';
214 require_once './libraries/select_server.lib.php';
215 PMA_select_server(false, false);
217 echo '</select></div>';
218 } else {
219 echo ' <input type="hidden" name="server" value="' . $GLOBALS['server'] . '" />';
220 } // end if (server choice)
222 </fieldset>
223 <fieldset class="tblFooters">
224 <input value="<?php echo $GLOBALS['strGo']; ?>" type="submit" />
225 <input type="hidden" name="lang" value="<?php echo $GLOBALS['lang']; ?>" />
226 <input type="hidden" name="convcharset" value="<?php echo htmlspecialchars($GLOBALS['convcharset'], ENT_QUOTES); ?>" />
227 <?php
228 if (!empty($GLOBALS['target'])) {
229 echo ' <input type="hidden" name="target" value="' . htmlspecialchars($GLOBALS['target']) . '" />' . "\n";
231 if (!empty($GLOBALS['db'])) {
232 echo ' <input type="hidden" name="db" value="' . htmlspecialchars($GLOBALS['db']) . '" />' . "\n";
234 if (!empty($GLOBALS['table'])) {
235 echo ' <input type="hidden" name="table" value="' . htmlspecialchars($GLOBALS['table']) . '" />' . "\n";
238 </fieldset>
239 </form>
240 <?php
241 // show the "Cookies required" message only if cookies are disabled
242 // (we previously tried to set some cookies)
243 if (empty($_COOKIE)) {
244 echo '<div class="notice">' . $GLOBALS['strCookiesRequired'] . '</div>' . "\n";
246 if (! empty($GLOBALS['PMA_errors']) && is_array($GLOBALS['PMA_errors'])) {
247 foreach ($GLOBALS['PMA_errors'] as $error) {
248 echo '<div class="error">' . $error . '</div>' . "\n";
251 // the warning is also displayed on main page but show it also here,
252 // because on some PHP versions running on 64-bit, the blowfish library
253 // does not work and this would prevent login
254 if (defined('PMA_WARN_FOR_MCRYPT')) {
255 echo '<div class="warning">' . PMA_sanitize(sprintf($GLOBALS['strCantLoad'], 'mcrypt')) . '</div>' . "\n";
258 </div>
259 <script type="text/javascript">
260 // <![CDATA[
261 function PMA_focusInput()
263 var input_username = document.getElementById('input_username');
264 var input_password = document.getElementById('input_password');
265 if (input_username.value == '') {
266 input_username.focus();
267 } else {
268 input_password.focus();
272 window.setTimeout('PMA_focusInput()', 500);
273 // ]]>
274 </script>
275 </body>
276 </html>
277 <?php
278 if (file_exists('./config.footer.inc.php')) {
279 require './config.footer.inc.php';
281 exit;
282 } // end of the 'PMA_auth()' function
286 * Gets advanced authentication settings
288 * this function DOES NOT check authentication - it just checks/provides
289 * authentication credentials required to connect to the MySQL server
290 * usally with PMA_DBI_connect()
292 * it returns false if there is missing something - which usally leads to
293 * PMA_auth() which displays login form
295 * it returns true if all seems ok which usally leads to PMA_auth_set_user()
297 * it directly switches to PMA_auth_fails() if user inactivity timout is reached
299 * @todo AllowArbitraryServer on does not imply that the user wnats an
300 * arbitrary server, or? so we should also check if this is filled and
301 * not only if allowed
302 * @uses $GLOBALS['PHP_AUTH_USER']
303 * @uses $GLOBALS['PHP_AUTH_PW']
304 * @uses $GLOBALS['no_activity']
305 * @uses $GLOBALS['server']
306 * @uses $GLOBALS['from_cookie']
307 * @uses $GLOBALS['pma_auth_server']
308 * @uses $cfg['blowfish_secret']
309 * @uses $cfg['AllowArbitraryServer']
310 * @uses $cfg['LoginCookieValidity']
311 * @uses $cfg['Servers']
312 * @uses $_REQUEST['old_usr'] from logout link
313 * @uses $_REQUEST['pma_username'] from login form
314 * @uses $_REQUEST['pma_password'] from login form
315 * @uses $_REQUEST['pma_servername'] from login form
316 * @uses $_COOKIE
317 * @uses $_SESSION['last_access_time']
318 * @uses PMA_removeCookie()
319 * @uses PMA_blowfish_decrypt()
320 * @uses PMA_auth_fails()
321 * @uses time()
323 * @return boolean whether we get authentication settings or not
325 * @access public
327 function PMA_auth_check()
329 // Initialization
331 * @global $GLOBALS['pma_auth_server'] the user provided server to connect to
333 $GLOBALS['pma_auth_server'] = '';
335 $GLOBALS['PHP_AUTH_USER'] = $GLOBALS['PHP_AUTH_PW'] = '';
336 $GLOBALS['from_cookie'] = false;
338 // avoid an error in mcrypt
339 if (empty($GLOBALS['cfg']['blowfish_secret'])) {
340 return false;
343 if (defined('PMA_CLEAR_COOKIES')) {
344 foreach($GLOBALS['cfg']['Servers'] as $key => $val) {
345 PMA_removeCookie('pmaPass-' . $key);
346 PMA_removeCookie('pmaServer-' . $key);
347 PMA_removeCookie('pmaUser-' . $key);
349 return false;
352 if (! empty($_REQUEST['old_usr'])) {
353 // The user wants to be logged out
354 // -> delete his choices that were stored in session
355 session_destroy();
356 // -> delete password cookie(s)
357 if ($GLOBALS['cfg']['LoginCookieDeleteAll']) {
358 foreach($GLOBALS['cfg']['Servers'] as $key => $val) {
359 PMA_removeCookie('pmaPass-' . $key);
360 if (isset($_COOKIE['pmaPass-' . $key])) {
361 unset($_COOKIE['pmaPass-' . $key]);
364 } else {
365 PMA_removeCookie('pmaPass-' . $GLOBALS['server']);
366 if (isset($_COOKIE['pmaPass-' . $GLOBALS['server']])) {
367 unset($_COOKIE['pmaPass-' . $GLOBALS['server']]);
372 if (! empty($_REQUEST['pma_username'])) {
373 // The user just logged in
374 $GLOBALS['PHP_AUTH_USER'] = $_REQUEST['pma_username'];
375 $GLOBALS['PHP_AUTH_PW'] = empty($_REQUEST['pma_password']) ? '' : $_REQUEST['pma_password'];
376 if ($GLOBALS['cfg']['AllowArbitraryServer'] && isset($_REQUEST['pma_servername'])) {
377 $GLOBALS['pma_auth_server'] = $_REQUEST['pma_servername'];
379 return true;
382 // At the end, try to set the $GLOBALS['PHP_AUTH_USER']
383 // and $GLOBALS['PHP_AUTH_PW'] variables from cookies
385 // servername
386 if ($GLOBALS['cfg']['AllowArbitraryServer']
387 && ! empty($_COOKIE['pmaServer-' . $GLOBALS['server']])) {
388 $GLOBALS['pma_auth_server'] = $_COOKIE['pmaServer-' . $GLOBALS['server']];
391 // username
392 if (empty($_COOKIE['pmaUser-' . $GLOBALS['server']])) {
393 return false;
396 $GLOBALS['PHP_AUTH_USER'] = PMA_blowfish_decrypt(
397 $_COOKIE['pmaUser-' . $GLOBALS['server']],
398 $GLOBALS['cfg']['blowfish_secret']);
400 // user was never logged in since session start
401 if (empty($_SESSION['last_access_time'])) {
402 return false;
405 // User inactive too long
406 if ($_SESSION['last_access_time'] < time() - $GLOBALS['cfg']['LoginCookieValidity']) {
407 $GLOBALS['no_activity'] = true;
408 PMA_auth_fails();
409 exit;
412 // password
413 if (empty($_COOKIE['pmaPass-' . $GLOBALS['server']])) {
414 return false;
417 $GLOBALS['PHP_AUTH_PW'] = PMA_blowfish_decrypt(
418 $_COOKIE['pmaPass-' . $GLOBALS['server']],
419 $GLOBALS['cfg']['blowfish_secret'] /* . $_SESSION['last_access_time'] */);
421 if ($GLOBALS['PHP_AUTH_PW'] == "\xff(blank)") {
422 $GLOBALS['PHP_AUTH_PW'] = '';
425 $GLOBALS['from_cookie'] = true;
427 return true;
428 } // end of the 'PMA_auth_check()' function
432 * Set the user and password after last checkings if required
434 * @uses $GLOBALS['PHP_AUTH_USER']
435 * @uses $GLOBALS['PHP_AUTH_PW']
436 * @uses $GLOBALS['server']
437 * @uses $GLOBALS['from_cookie']
438 * @uses $GLOBALS['pma_auth_server']
439 * @uses $cfg['Server']
440 * @uses $cfg['AllowArbitraryServer']
441 * @uses $cfg['blowfish_secret']
442 * @uses $cfg['LoginCookieStore']
443 * @uses $cfg['PmaAbsoluteUri']
444 * @uses $_SESSION['last_access_time']
445 * @uses PMA_COMING_FROM_COOKIE_LOGIN
446 * @uses PMA_setCookie()
447 * @uses PMA_blowfish_encrypt()
448 * @uses PMA_removeCookie()
449 * @uses PMA_sendHeaderLocation()
450 * @uses time()
451 * @uses define()
452 * @return boolean always true
454 * @access public
456 function PMA_auth_set_user()
458 global $cfg;
460 // Ensures valid authentication mode, 'only_db', bookmark database and
461 // table names and relation table name are used
462 if ($cfg['Server']['user'] != $GLOBALS['PHP_AUTH_USER']) {
463 foreach ($cfg['Servers'] as $idx => $current) {
464 if ($current['host'] == $cfg['Server']['host']
465 && $current['port'] == $cfg['Server']['port']
466 && $current['socket'] == $cfg['Server']['socket']
467 && $current['ssl'] == $cfg['Server']['ssl']
468 && $current['connect_type'] == $cfg['Server']['connect_type']
469 && $current['user'] == $GLOBALS['PHP_AUTH_USER']) {
470 $GLOBALS['server'] = $idx;
471 $cfg['Server'] = $current;
472 break;
474 } // end foreach
475 } // end if
477 $pma_server_changed = false;
478 if ($GLOBALS['cfg']['AllowArbitraryServer']
479 && ! empty($GLOBALS['pma_auth_server'])
480 && $cfg['Server']['host'] != $GLOBALS['pma_auth_server']) {
481 $cfg['Server']['host'] = $GLOBALS['pma_auth_server'];
482 $pma_server_changed = true;
484 $cfg['Server']['user'] = $GLOBALS['PHP_AUTH_USER'];
485 $cfg['Server']['password'] = $GLOBALS['PHP_AUTH_PW'];
487 $_SESSION['last_access_time'] = time();
489 // Name and password cookies needs to be refreshed each time
490 // Duration = one month for username
491 PMA_setCookie('pmaUser-' . $GLOBALS['server'],
492 PMA_blowfish_encrypt($cfg['Server']['user'],
493 $GLOBALS['cfg']['blowfish_secret']));
495 // Duration = as configured
496 PMA_setCookie('pmaPass-' . $GLOBALS['server'],
497 PMA_blowfish_encrypt(!empty($cfg['Server']['password']) ? $cfg['Server']['password'] : "\xff(blank)",
498 $GLOBALS['cfg']['blowfish_secret'] /* . $_SESSION['last_access_time'] */),
499 null,
500 $GLOBALS['cfg']['LoginCookieStore']);
502 // Set server cookies if required (once per session) and, in this case, force
503 // reload to ensure the client accepts cookies
504 if (! $GLOBALS['from_cookie']) {
505 if ($GLOBALS['cfg']['AllowArbitraryServer']) {
506 if (! empty($GLOBALS['pma_auth_server'])) {
507 // Duration = one month for serverrname
508 PMA_setCookie('pmaServer-' . $GLOBALS['server'], $cfg['Server']['host']);
509 } else {
510 // Delete servername cookie
511 PMA_removeCookie('pmaServer-' . $GLOBALS['server']);
515 // URL where to go:
516 $redirect_url = $cfg['PmaAbsoluteUri'] . 'index.php';
518 // any parameters to pass?
519 $url_params = array();
520 if (strlen($GLOBALS['db'])) {
521 $url_params['db'] = $GLOBALS['db'];
523 if (strlen($GLOBALS['table'])) {
524 $url_params['table'] = $GLOBALS['table'];
526 // Language change from the login panel needs to be remembered
527 if (! empty($GLOBALS['lang'])) {
528 $url_params['lang'] = $GLOBALS['lang'];
530 // any target to pass?
531 if (! empty($GLOBALS['target']) && $GLOBALS['target'] != 'index.php') {
532 $url_params['target'] = $GLOBALS['target'];
536 * whether we come from a fresh cookie login
538 define('PMA_COMING_FROM_COOKIE_LOGIN', true);
539 PMA_sendHeaderLocation($redirect_url . PMA_generate_common_url($url_params, '&'));
540 exit();
541 } // end if
543 return true;
544 } // end of the 'PMA_auth_set_user()' function
548 * User is not allowed to login to MySQL -> authentication failed
550 * prepares error message and switches to PMA_auth() which display the error
551 * and the login form
553 * this function MUST exit/quit the application,
554 * currently doen by call to PMA_auth()
556 * @todo $php_errormsg is invalid here!? it will never be set in this scope
557 * @uses $GLOBALS['server']
558 * @uses $GLOBALS['allowDeny_forbidden']
559 * @uses $GLOBALS['strAccessDenied']
560 * @uses $GLOBALS['strNoActivity']
561 * @uses $GLOBALS['strCannotLogin']
562 * @uses $GLOBALS['no_activity']
563 * @uses $cfg['LoginCookieValidity']
564 * @uses PMA_removeCookie()
565 * @uses PMA_getenv()
566 * @uses PMA_DBI_getError()
567 * @uses PMA_sanitize()
568 * @uses PMA_auth()
569 * @uses sprintf()
570 * @uses basename()
571 * @access public
573 function PMA_auth_fails()
575 global $conn_error;
577 // Deletes password cookie and displays the login form
578 PMA_removeCookie('pmaPass-' . $GLOBALS['server']);
580 if (! empty($GLOBALS['allowDeny_forbidden'])) {
581 $conn_error = $GLOBALS['strAccessDenied'];
582 } elseif (! empty($GLOBALS['no_activity'])) {
583 $conn_error = sprintf($GLOBALS['strNoActivity'], $GLOBALS['cfg']['LoginCookieValidity']);
584 // Remember where we got timeout to return on same place
585 if (PMA_getenv('SCRIPT_NAME')) {
586 $GLOBALS['target'] = basename(PMA_getenv('SCRIPT_NAME'));
587 // avoid "missing parameter: field" on re-entry
588 if ('tbl_alter.php' == $GLOBALS['target']) {
589 $GLOBALS['target'] = 'tbl_structure.php';
592 } elseif (PMA_DBI_getError()) {
593 $conn_error = PMA_sanitize(PMA_DBI_getError());
594 } elseif (isset($php_errormsg)) {
595 $conn_error = $php_errormsg;
596 } else {
597 $conn_error = $GLOBALS['strCannotLogin'];
600 PMA_auth();
601 } // end of the 'PMA_auth_fails()' function