PageRenderTime 48ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/phpmyadmin/libraries/auth/cookie.auth.lib.php

https://bitbucket.org/adarshj/convenient_website
PHP | 594 lines | 363 code | 69 blank | 162 comment | 88 complexity | ba5e26450e5af300ac64f2c742a31309 MD5 | raw file
Possible License(s): Apache-2.0, MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-2-Clause, GPL-2.0, LGPL-3.0
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Set of functions used to run cookie based authentication.
  5. *
  6. * @package PhpMyAdmin-Auth-Cookie
  7. */
  8. if (! defined('PHPMYADMIN')) {
  9. exit;
  10. }
  11. /**
  12. * Swekey authentication functions.
  13. */
  14. require './libraries/auth/swekey/swekey.auth.lib.php';
  15. if (function_exists('mcrypt_encrypt')) {
  16. /**
  17. * Uses faster mcrypt library if available
  18. * (as this is not called from anywhere else, put the code in-line
  19. * for faster execution)
  20. */
  21. /**
  22. * Initialization
  23. * Store the initialization vector because it will be needed for
  24. * further decryption. I don't think necessary to have one iv
  25. * per server so I don't put the server number in the cookie name.
  26. */
  27. if (empty($_COOKIE['pma_mcrypt_iv']) || false === ($iv = base64_decode($_COOKIE['pma_mcrypt_iv'], true))) {
  28. srand((double) microtime() * 1000000);
  29. $td = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_CBC, '');
  30. if ($td === false) {
  31. die(__('Failed to use Blowfish from mcrypt!'));
  32. }
  33. $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
  34. $GLOBALS['PMA_Config']->setCookie('pma_mcrypt_iv', base64_encode($iv));
  35. }
  36. /**
  37. * Encryption using blowfish algorithm (mcrypt)
  38. *
  39. * @param string original data
  40. * @param string the secret
  41. *
  42. * @return string the encrypted result
  43. *
  44. * @access public
  45. *
  46. */
  47. function PMA_blowfish_encrypt($data, $secret)
  48. {
  49. global $iv;
  50. return base64_encode(mcrypt_encrypt(MCRYPT_BLOWFISH, $secret, $data, MCRYPT_MODE_CBC, $iv));
  51. }
  52. /**
  53. * Decryption using blowfish algorithm (mcrypt)
  54. *
  55. * @param string encrypted data
  56. * @param string the secret
  57. *
  58. * @return string original data
  59. *
  60. * @access public
  61. *
  62. */
  63. function PMA_blowfish_decrypt($encdata, $secret)
  64. {
  65. global $iv;
  66. return trim(mcrypt_decrypt(MCRYPT_BLOWFISH, $secret, base64_decode($encdata), MCRYPT_MODE_CBC, $iv));
  67. }
  68. } else {
  69. include_once './libraries/blowfish.php';
  70. }
  71. /**
  72. * Returns blowfish secret or generates one if needed.
  73. *
  74. * @access public
  75. * @return string
  76. */
  77. function PMA_get_blowfish_secret()
  78. {
  79. if (empty($GLOBALS['cfg']['blowfish_secret'])) {
  80. if (empty($_SESSION['auto_blowfish_secret'])) {
  81. // this returns 23 characters
  82. $_SESSION['auto_blowfish_secret'] = uniqid('', true);
  83. }
  84. return $_SESSION['auto_blowfish_secret'];
  85. } else {
  86. // apply md5() to work around too long secrets (returns 32 characters)
  87. return md5($GLOBALS['cfg']['blowfish_secret']);
  88. }
  89. }
  90. /**
  91. * Displays authentication form
  92. *
  93. * this function MUST exit/quit the application
  94. *
  95. * @global string the last connection error
  96. *
  97. * @access public
  98. */
  99. function PMA_auth()
  100. {
  101. global $conn_error;
  102. /* Perform logout to custom URL */
  103. if (! empty($_REQUEST['old_usr'])
  104. && ! empty($GLOBALS['cfg']['Server']['LogoutURL'])) {
  105. PMA_sendHeaderLocation($GLOBALS['cfg']['Server']['LogoutURL']);
  106. exit;
  107. }
  108. /* No recall if blowfish secret is not configured as it would produce garbage */
  109. if ($GLOBALS['cfg']['LoginCookieRecall'] && !empty($GLOBALS['cfg']['blowfish_secret'])) {
  110. $default_user = $GLOBALS['PHP_AUTH_USER'];
  111. $default_server = $GLOBALS['pma_auth_server'];
  112. $autocomplete = '';
  113. } else {
  114. $default_user = '';
  115. $default_server = '';
  116. // skip the IE autocomplete feature.
  117. $autocomplete = ' autocomplete="off"';
  118. }
  119. $cell_align = ($GLOBALS['text_dir'] == 'ltr') ? 'left' : 'right';
  120. // Defines the charset to be used
  121. header('Content-Type: text/html; charset=utf-8');
  122. /* HTML header; do not show here the PMA version to improve security */
  123. $page_title = 'phpMyAdmin ';
  124. include './libraries/header_meta_style.inc.php';
  125. // if $page_title is set, this script uses it as the title:
  126. include './libraries/header_scripts.inc.php';
  127. ?>
  128. <script type="text/javascript">
  129. //<![CDATA[
  130. // show login form in top frame
  131. if (top != self) {
  132. window.top.location.href=location;
  133. }
  134. //]]>
  135. </script>
  136. </head>
  137. <body class="loginform">
  138. <?php
  139. if (file_exists(CUSTOM_HEADER_FILE)) {
  140. include CUSTOM_HEADER_FILE;
  141. }
  142. ?>
  143. <div class="container">
  144. <a href="<?php echo PMA_linkURL('http://www.phpmyadmin.net/'); ?>" target="_blank" class="logo"><?php
  145. $logo_image = $GLOBALS['pmaThemeImage'] . 'logo_right.png';
  146. if (@file_exists($logo_image)) {
  147. echo '<img src="' . $logo_image . '" id="imLogo" name="imLogo" alt="phpMyAdmin" border="0" />';
  148. } else {
  149. echo '<img name="imLogo" id="imLogo" src="' . $GLOBALS['pmaThemeImage'] . 'pma_logo.png' . '" '
  150. . 'border="0" width="88" height="31" alt="phpMyAdmin" />';
  151. }
  152. ?></a>
  153. <h1>
  154. <?php
  155. echo sprintf(__('Welcome to %s'),
  156. '<bdo dir="ltr" xml:lang="en">' . $page_title . '</bdo>');
  157. ?>
  158. </h1>
  159. <?php
  160. // Show error message
  161. if (! empty($conn_error)) {
  162. PMA_Message::rawError($conn_error)->display();
  163. }
  164. // Displays the languages form
  165. if (empty($GLOBALS['cfg']['Lang'])) {
  166. include_once './libraries/display_select_lang.lib.php';
  167. // use fieldset, don't show doc link
  168. PMA_select_language(true, false);
  169. }
  170. ?>
  171. <br />
  172. <!-- Login form -->
  173. <form method="post" action="index.php" name="login_form"<?php echo $autocomplete; ?> target="_top" class="login">
  174. <fieldset>
  175. <legend>
  176. <?php
  177. echo __('Log in');
  178. echo '<a href="./Documentation.html" target="documentation" ' .
  179. 'title="' . __('phpMyAdmin documentation') . '"> ';
  180. if ($GLOBALS['cfg']['ReplaceHelpImg']) {
  181. echo PMA_getImage('b_help.png', __('phpMyAdmin documentation'));
  182. } else {
  183. echo '(*)';
  184. }
  185. echo '</a>';
  186. ?>
  187. </legend>
  188. <?php if ($GLOBALS['cfg']['AllowArbitraryServer']) { ?>
  189. <div class="item">
  190. <label for="input_servername" title="<?php echo __('You can enter hostname/IP address and port separated by space.'); ?>"><?php echo __('Server:'); ?></label>
  191. <input type="text" name="pma_servername" id="input_servername" value="<?php echo htmlspecialchars($default_server); ?>" size="24" class="textfield" title="<?php echo __('You can enter hostname/IP address and port separated by space.'); ?>" />
  192. </div>
  193. <?php } ?>
  194. <div class="item">
  195. <label for="input_username"><?php echo __('Username:'); ?></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 __('Password:'); ?></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) {
  204. ?>
  205. <div class="item">
  206. <label for="select_server"><?php echo __('Server Choice'); ?>:</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 = \'\'" ';
  211. }
  212. echo '>';
  213. include_once './libraries/select_server.lib.php';
  214. PMA_select_server(false, false);
  215. echo '</select></div>';
  216. } else {
  217. echo ' <input type="hidden" name="server" value="' . $GLOBALS['server'] . '" />';
  218. } // end if (server choice)
  219. ?>
  220. </fieldset>
  221. <fieldset class="tblFooters">
  222. <input value="<?php echo __('Go'); ?>" type="submit" id="input_go" />
  223. <?php
  224. $_form_params = array();
  225. if (! empty($GLOBALS['target'])) {
  226. $_form_params['target'] = $GLOBALS['target'];
  227. }
  228. if (! empty($GLOBALS['db'])) {
  229. $_form_params['db'] = $GLOBALS['db'];
  230. }
  231. if (! empty($GLOBALS['table'])) {
  232. $_form_params['table'] = $GLOBALS['table'];
  233. }
  234. // do not generate a "server" hidden field as we want the "server"
  235. // drop-down to have priority
  236. echo PMA_generate_common_hidden_inputs($_form_params, '', 0, 'server');
  237. ?>
  238. </fieldset>
  239. </form>
  240. <?php
  241. // BEGIN Swekey Integration
  242. Swekey_login('input_username', 'input_go');
  243. // END Swekey Integration
  244. // show the "Cookies required" message only if cookies are disabled
  245. // (we previously tried to set some cookies)
  246. if (empty($_COOKIE)) {
  247. trigger_error(__('Cookies must be enabled past this point.'), E_USER_NOTICE);
  248. }
  249. if ($GLOBALS['error_handler']->hasDisplayErrors()) {
  250. echo '<div>';
  251. $GLOBALS['error_handler']->dispErrors();
  252. echo '</div>';
  253. }
  254. ?>
  255. </div>
  256. <?php
  257. if (file_exists(CUSTOM_FOOTER_FILE)) {
  258. include CUSTOM_FOOTER_FILE;
  259. }
  260. ?>
  261. </body>
  262. </html>
  263. <?php
  264. exit;
  265. } // end of the 'PMA_auth()' function
  266. /**
  267. * Gets advanced authentication settings
  268. *
  269. * this function DOES NOT check authentication - it just checks/provides
  270. * authentication credentials required to connect to the MySQL server
  271. * usually with PMA_DBI_connect()
  272. *
  273. * it returns false if something is missing - which usually leads to
  274. * PMA_auth() which displays login form
  275. *
  276. * it returns true if all seems ok which usually leads to PMA_auth_set_user()
  277. *
  278. * it directly switches to PMA_auth_fails() if user inactivity timout is reached
  279. *
  280. * @todo AllowArbitraryServer on does not imply that the user wants an
  281. * arbitrary server, or? so we should also check if this is filled and
  282. * not only if allowed
  283. *
  284. * @return boolean whether we get authentication settings or not
  285. *
  286. * @access public
  287. */
  288. function PMA_auth_check()
  289. {
  290. // Initialization
  291. /**
  292. * @global $GLOBALS['pma_auth_server'] the user provided server to connect to
  293. */
  294. $GLOBALS['pma_auth_server'] = '';
  295. $GLOBALS['PHP_AUTH_USER'] = $GLOBALS['PHP_AUTH_PW'] = '';
  296. $GLOBALS['from_cookie'] = false;
  297. // BEGIN Swekey Integration
  298. if (! Swekey_auth_check()) {
  299. return false;
  300. }
  301. // END Swekey Integration
  302. if (defined('PMA_CLEAR_COOKIES')) {
  303. foreach ($GLOBALS['cfg']['Servers'] as $key => $val) {
  304. $GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $key);
  305. $GLOBALS['PMA_Config']->removeCookie('pmaServer-' . $key);
  306. $GLOBALS['PMA_Config']->removeCookie('pmaUser-' . $key);
  307. }
  308. return false;
  309. }
  310. if (! empty($_REQUEST['old_usr'])) {
  311. // The user wants to be logged out
  312. // -> delete his choices that were stored in session
  313. // according to the PHP manual we should do this before the destroy:
  314. //$_SESSION = array();
  315. // but we still need some parts of the session information
  316. // in libraries/header_meta_style.inc.php
  317. session_destroy();
  318. // -> delete password cookie(s)
  319. if ($GLOBALS['cfg']['LoginCookieDeleteAll']) {
  320. foreach ($GLOBALS['cfg']['Servers'] as $key => $val) {
  321. $GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $key);
  322. if (isset($_COOKIE['pmaPass-' . $key])) {
  323. unset($_COOKIE['pmaPass-' . $key]);
  324. }
  325. }
  326. } else {
  327. $GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $GLOBALS['server']);
  328. if (isset($_COOKIE['pmaPass-' . $GLOBALS['server']])) {
  329. unset($_COOKIE['pmaPass-' . $GLOBALS['server']]);
  330. }
  331. }
  332. }
  333. if (! empty($_REQUEST['pma_username'])) {
  334. // The user just logged in
  335. $GLOBALS['PHP_AUTH_USER'] = $_REQUEST['pma_username'];
  336. $GLOBALS['PHP_AUTH_PW'] = empty($_REQUEST['pma_password']) ? '' : $_REQUEST['pma_password'];
  337. if ($GLOBALS['cfg']['AllowArbitraryServer'] && isset($_REQUEST['pma_servername'])) {
  338. $GLOBALS['pma_auth_server'] = $_REQUEST['pma_servername'];
  339. }
  340. return true;
  341. }
  342. // At the end, try to set the $GLOBALS['PHP_AUTH_USER']
  343. // and $GLOBALS['PHP_AUTH_PW'] variables from cookies
  344. // servername
  345. if ($GLOBALS['cfg']['AllowArbitraryServer']
  346. && ! empty($_COOKIE['pmaServer-' . $GLOBALS['server']])) {
  347. $GLOBALS['pma_auth_server'] = $_COOKIE['pmaServer-' . $GLOBALS['server']];
  348. }
  349. // username
  350. if (empty($_COOKIE['pmaUser-' . $GLOBALS['server']])) {
  351. return false;
  352. }
  353. $GLOBALS['PHP_AUTH_USER'] = PMA_blowfish_decrypt(
  354. $_COOKIE['pmaUser-' . $GLOBALS['server']],
  355. PMA_get_blowfish_secret());
  356. // user was never logged in since session start
  357. if (empty($_SESSION['last_access_time'])) {
  358. return false;
  359. }
  360. // User inactive too long
  361. if ($_SESSION['last_access_time'] < time() - $GLOBALS['cfg']['LoginCookieValidity']) {
  362. PMA_cacheUnset('is_create_db_priv', true);
  363. PMA_cacheUnset('is_process_priv', true);
  364. PMA_cacheUnset('is_reload_priv', true);
  365. PMA_cacheUnset('db_to_create', true);
  366. PMA_cacheUnset('dbs_where_create_table_allowed', true);
  367. $GLOBALS['no_activity'] = true;
  368. PMA_auth_fails();
  369. exit;
  370. }
  371. // password
  372. if (empty($_COOKIE['pmaPass-' . $GLOBALS['server']])) {
  373. return false;
  374. }
  375. $GLOBALS['PHP_AUTH_PW'] = PMA_blowfish_decrypt(
  376. $_COOKIE['pmaPass-' . $GLOBALS['server']],
  377. PMA_get_blowfish_secret());
  378. if ($GLOBALS['PHP_AUTH_PW'] == "\xff(blank)") {
  379. $GLOBALS['PHP_AUTH_PW'] = '';
  380. }
  381. $GLOBALS['from_cookie'] = true;
  382. return true;
  383. } // end of the 'PMA_auth_check()' function
  384. /**
  385. * Set the user and password after last checkings if required
  386. *
  387. * @return boolean always true
  388. *
  389. * @access public
  390. */
  391. function PMA_auth_set_user()
  392. {
  393. global $cfg;
  394. // Ensures valid authentication mode, 'only_db', bookmark database and
  395. // table names and relation table name are used
  396. if ($cfg['Server']['user'] != $GLOBALS['PHP_AUTH_USER']) {
  397. foreach ($cfg['Servers'] as $idx => $current) {
  398. if ($current['host'] == $cfg['Server']['host']
  399. && $current['port'] == $cfg['Server']['port']
  400. && $current['socket'] == $cfg['Server']['socket']
  401. && $current['ssl'] == $cfg['Server']['ssl']
  402. && $current['connect_type'] == $cfg['Server']['connect_type']
  403. && $current['user'] == $GLOBALS['PHP_AUTH_USER']) {
  404. $GLOBALS['server'] = $idx;
  405. $cfg['Server'] = $current;
  406. break;
  407. }
  408. } // end foreach
  409. } // end if
  410. if ($GLOBALS['cfg']['AllowArbitraryServer']
  411. && ! empty($GLOBALS['pma_auth_server'])) {
  412. /* Allow to specify 'host port' */
  413. $parts = explode(' ', $GLOBALS['pma_auth_server']);
  414. if (count($parts) == 2) {
  415. $tmp_host = $parts[0];
  416. $tmp_port = $parts[1];
  417. } else {
  418. $tmp_host = $GLOBALS['pma_auth_server'];
  419. $tmp_port = '';
  420. }
  421. if ($cfg['Server']['host'] != $GLOBALS['pma_auth_server']) {
  422. $cfg['Server']['host'] = $tmp_host;
  423. if (!empty($tmp_port)) {
  424. $cfg['Server']['port'] = $tmp_port;
  425. }
  426. }
  427. unset($tmp_host, $tmp_port, $parts);
  428. }
  429. $cfg['Server']['user'] = $GLOBALS['PHP_AUTH_USER'];
  430. $cfg['Server']['password'] = $GLOBALS['PHP_AUTH_PW'];
  431. // Avoid showing the password in phpinfo()'s output
  432. unset($GLOBALS['PHP_AUTH_PW']);
  433. unset($_SERVER['PHP_AUTH_PW']);
  434. $_SESSION['last_access_time'] = time();
  435. // Name and password cookies need to be refreshed each time
  436. // Duration = one month for username
  437. $GLOBALS['PMA_Config']->setCookie('pmaUser-' . $GLOBALS['server'],
  438. PMA_blowfish_encrypt($cfg['Server']['user'],
  439. PMA_get_blowfish_secret()));
  440. // Duration = as configured
  441. $GLOBALS['PMA_Config']->setCookie('pmaPass-' . $GLOBALS['server'],
  442. PMA_blowfish_encrypt(!empty($cfg['Server']['password']) ? $cfg['Server']['password'] : "\xff(blank)",
  443. PMA_get_blowfish_secret()),
  444. null,
  445. $GLOBALS['cfg']['LoginCookieStore']);
  446. // Set server cookies if required (once per session) and, in this case, force
  447. // reload to ensure the client accepts cookies
  448. if (! $GLOBALS['from_cookie']) {
  449. if ($GLOBALS['cfg']['AllowArbitraryServer']) {
  450. if (! empty($GLOBALS['pma_auth_server'])) {
  451. // Duration = one month for servername
  452. $GLOBALS['PMA_Config']->setCookie('pmaServer-' . $GLOBALS['server'], $cfg['Server']['host']);
  453. } else {
  454. // Delete servername cookie
  455. $GLOBALS['PMA_Config']->removeCookie('pmaServer-' . $GLOBALS['server']);
  456. }
  457. }
  458. // URL where to go:
  459. $redirect_url = $cfg['PmaAbsoluteUri'] . 'index.php';
  460. // any parameters to pass?
  461. $url_params = array();
  462. if (strlen($GLOBALS['db'])) {
  463. $url_params['db'] = $GLOBALS['db'];
  464. }
  465. if (strlen($GLOBALS['table'])) {
  466. $url_params['table'] = $GLOBALS['table'];
  467. }
  468. // any target to pass?
  469. if (! empty($GLOBALS['target']) && $GLOBALS['target'] != 'index.php') {
  470. $url_params['target'] = $GLOBALS['target'];
  471. }
  472. /**
  473. * whether we come from a fresh cookie login
  474. */
  475. define('PMA_COMING_FROM_COOKIE_LOGIN', true);
  476. /**
  477. * Clear user cache.
  478. */
  479. PMA_clearUserCache();
  480. PMA_sendHeaderLocation($redirect_url . PMA_generate_common_url($url_params, '&'));
  481. exit();
  482. } // end if
  483. return true;
  484. } // end of the 'PMA_auth_set_user()' function
  485. /**
  486. * User is not allowed to login to MySQL -> authentication failed
  487. *
  488. * prepares error message and switches to PMA_auth() which display the error
  489. * and the login form
  490. *
  491. * this function MUST exit/quit the application,
  492. * currently doen by call to PMA_auth()
  493. *
  494. * @access public
  495. */
  496. function PMA_auth_fails()
  497. {
  498. global $conn_error;
  499. // Deletes password cookie and displays the login form
  500. $GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $GLOBALS['server']);
  501. if (! empty($GLOBALS['login_without_password_is_forbidden'])) {
  502. $conn_error = __('Login without a password is forbidden by configuration (see AllowNoPassword)');
  503. } elseif (! empty($GLOBALS['allowDeny_forbidden'])) {
  504. $conn_error = __('Access denied');
  505. } elseif (! empty($GLOBALS['no_activity'])) {
  506. $conn_error = sprintf(__('No activity within %s seconds; please log in again'), $GLOBALS['cfg']['LoginCookieValidity']);
  507. // Remember where we got timeout to return on same place
  508. if (PMA_getenv('SCRIPT_NAME')) {
  509. $GLOBALS['target'] = basename(PMA_getenv('SCRIPT_NAME'));
  510. // avoid "missing parameter: field" on re-entry
  511. if ('tbl_alter.php' == $GLOBALS['target']) {
  512. $GLOBALS['target'] = 'tbl_structure.php';
  513. }
  514. }
  515. } elseif (PMA_DBI_getError()) {
  516. $conn_error = '#' . $GLOBALS['errno'] . ' ' . __('Cannot log in to the MySQL server');
  517. } else {
  518. $conn_error = __('Cannot log in to the MySQL server');
  519. }
  520. // needed for PHP-CGI (not need for FastCGI or mod-php)
  521. header('Cache-Control: no-store, no-cache, must-revalidate');
  522. header('Pragma: no-cache');
  523. PMA_auth();
  524. } // end of the 'PMA_auth_fails()' function
  525. ?>