Compare commits
220 Commits
master
...
MAINT_4_0_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5f1555e1b | ||
|
|
79f0afbd33 | ||
|
|
9a9a6ab709 | ||
|
|
83ea1f5e4f | ||
|
|
b6ca92cc75 | ||
|
|
1f859b1b15 | ||
|
|
ebb97a3960 | ||
|
|
f9a74deeb6 | ||
|
|
3d8b97b255 | ||
|
|
567b27487e | ||
|
|
4b5f3f9a12 | ||
|
|
88cc11ab13 | ||
|
|
801485a7f4 | ||
|
|
f8ad5bd759 | ||
|
|
8a0816266c | ||
|
|
00607e6041 | ||
|
|
3d230b6ab7 | ||
|
|
7fe97a1f3c | ||
|
|
afe84645f2 | ||
|
|
69b4b5c7f5 | ||
|
|
8783113cec | ||
|
|
6703597772 | ||
|
|
337b38044d | ||
|
|
54875fffc1 | ||
|
|
be5196ba44 | ||
|
|
5e108a340f | ||
|
|
773f126c89 | ||
|
|
63b7f6c0a9 | ||
|
|
af7c589391 | ||
|
|
0c3dfd186c | ||
|
|
d37abc38da | ||
|
|
67700620db | ||
|
|
b2605ebba6 | ||
|
|
096856c70c | ||
|
|
c2f7a898dd | ||
|
|
f2add98bd9 | ||
|
|
6117ad5cef | ||
|
|
58245cb1cc | ||
|
|
285e5623b6 | ||
|
|
5ba96c8804 | ||
|
|
12db0baeae | ||
|
|
2922cb7c70 | ||
|
|
533ffa4942 | ||
|
|
126321da37 | ||
|
|
b0e66715ba | ||
|
|
262aa8ec73 | ||
|
|
47d00af08a | ||
|
|
eec14404a7 | ||
|
|
ac703223e9 | ||
|
|
4d15f6b131 | ||
|
|
d03954bf9c | ||
|
|
f261abbdf9 | ||
|
|
5a28b63f9c | ||
|
|
ae8693db68 | ||
|
|
85e1d6ec80 | ||
|
|
378c3820bf | ||
|
|
6f8eb0993d | ||
|
|
e8c5cab3c1 | ||
|
|
714818f3ad | ||
|
|
ab26a8fe97 | ||
|
|
0f87b73ae2 | ||
|
|
04156efeb0 | ||
|
|
31546255f3 | ||
|
|
09a427b288 | ||
|
|
8f3ee9f9db | ||
|
|
56e1350118 | ||
|
|
7f7a8ac467 | ||
|
|
ff88cdbed2 | ||
|
|
8ac57b1281 | ||
|
|
fec9b98a22 | ||
|
|
a3953f88ef | ||
|
|
80c93025a7 | ||
|
|
8e0918cc41 | ||
|
|
bdc7436c77 | ||
|
|
14fd275811 | ||
|
|
c8297b4718 | ||
|
|
ab05803a42 | ||
|
|
41684ff1a1 | ||
|
|
e9a4de70a7 | ||
|
|
0a4cdc25f1 | ||
|
|
63a5fdaa21 | ||
|
|
a416cbe6c7 | ||
|
|
6cbbcdb719 | ||
|
|
dc25189741 | ||
|
|
ee6557a689 | ||
|
|
ec2bd5d84c | ||
|
|
4440790902 | ||
|
|
eb2c702ab2 | ||
|
|
a9005b20bc | ||
|
|
cf2e0afdb7 | ||
|
|
95b7b7d6dd | ||
|
|
59e0f3dee4 | ||
|
|
34a1cebf76 | ||
|
|
c6cfb58834 | ||
|
|
e46fdb8e5e | ||
|
|
01673e94dd | ||
|
|
83416df64f | ||
|
|
c3d22bee08 | ||
|
|
b04150e30e | ||
|
|
b974b56781 | ||
|
|
9b6f64b8b9 | ||
|
|
351019c074 | ||
|
|
8c336ba285 | ||
|
|
02971f754f | ||
|
|
abfd97983a | ||
|
|
e13f9862ef | ||
|
|
32875196f9 | ||
|
|
288efea5b4 | ||
|
|
f662d591c5 | ||
|
|
975089b8c3 | ||
|
|
78f6c54f1b | ||
|
|
5fefa51139 | ||
|
|
c795a395ba | ||
|
|
c93c82ee9c | ||
|
|
fa7a9b787b | ||
|
|
96c6a7c0a2 | ||
|
|
e1eb5e8e89 | ||
|
|
8451a7a5d2 | ||
|
|
c9faf855a0 | ||
|
|
6b52ae4d19 | ||
|
|
805225a28c | ||
|
|
75724a361b | ||
|
|
bf7379771f | ||
|
|
ee10ed1306 | ||
|
|
d26422eae5 | ||
|
|
b2054a1834 | ||
|
|
82fc97b15e | ||
|
|
b19c426726 | ||
|
|
27505e1c2d | ||
|
|
6f413680b1 | ||
|
|
b1cc43ee7f | ||
|
|
fe3be9f4b9 | ||
|
|
7ddce5e39a | ||
|
|
e795141fba | ||
|
|
25a632a9f4 | ||
|
|
155876b48f | ||
|
|
45ecc10d18 | ||
|
|
0667ea8ac7 | ||
|
|
73c8245a3d | ||
|
|
b8f1e0f325 | ||
|
|
945c58b9d2 | ||
|
|
f166893777 | ||
|
|
8b3ac5f5e3 | ||
|
|
04a20d5435 | ||
|
|
bf2fde282e | ||
|
|
3f9c1680c0 | ||
|
|
f9b36a377a | ||
|
|
d4447a53fa | ||
|
|
7ca28f105b | ||
|
|
1e5d12abcd | ||
|
|
6babab9874 | ||
|
|
9b5c64e14d | ||
|
|
ed9e2b474d | ||
|
|
c1377f30a2 | ||
|
|
e167f5ade9 | ||
|
|
2cc9f56559 | ||
|
|
00c64c6dde | ||
|
|
16e2f464ff | ||
|
|
f1ceadaa46 | ||
|
|
10dd46fca4 | ||
|
|
632380d3d9 | ||
|
|
555e73f177 | ||
|
|
980ccb6ffb | ||
|
|
28b5882b96 | ||
|
|
16136ea0ef | ||
|
|
5b79467245 | ||
|
|
25738352df | ||
|
|
7056ca9458 | ||
|
|
215f4a8ebe | ||
|
|
8023340a25 | ||
|
|
fe62b69a5b | ||
|
|
27eb98faed | ||
|
|
6fe54dfa00 | ||
|
|
2369daa7f5 | ||
|
|
6a96e67487 | ||
|
|
0ce4fd2750 | ||
|
|
9f3488fc3a | ||
|
|
ac81596bfc | ||
|
|
66149607b1 | ||
|
|
f79d30dd98 | ||
|
|
2694c36ef6 | ||
|
|
9730b16dd0 | ||
|
|
d81165f345 | ||
|
|
e97e7fb0ea | ||
|
|
fea1d39fef | ||
|
|
a395665715 | ||
|
|
e1a68ad02c | ||
|
|
5004dc4098 | ||
|
|
1da7417fc2 | ||
|
|
394bf9183c | ||
|
|
9b7fbe29ce | ||
|
|
26ce63dbde | ||
|
|
853f7255c5 | ||
|
|
9daeaff5f0 | ||
|
|
00828f9ccb | ||
|
|
095729d812 | ||
|
|
13a288d0da | ||
|
|
c7685e5acd | ||
|
|
c5783321cd | ||
|
|
2e3f0b9457 | ||
|
|
58cdd91fc8 | ||
|
|
42b64e12b5 | ||
|
|
d0f7dc7990 | ||
|
|
a150ea1df4 | ||
|
|
57594febab | ||
|
|
5118938f10 | ||
|
|
c6c77589a5 | ||
|
|
ceb7d7e1b2 | ||
|
|
ab0dba4533 | ||
|
|
5e52612841 | ||
|
|
098caf93b6 | ||
|
|
5cd9839467 | ||
|
|
03b92aa6e9 | ||
|
|
3668255202 | ||
|
|
0433d463b6 | ||
|
|
285ed5b8d3 | ||
|
|
f86761326c | ||
|
|
a92753bd65 | ||
|
|
1b55924356 | ||
|
|
82161a6c30 |
15
.travis.yml
15
.travis.yml
@ -2,5 +2,16 @@ language: php
|
||||
php:
|
||||
- "5.4"
|
||||
- "5.3"
|
||||
before_script: ./scripts/generate-mo --quiet
|
||||
script: phpunit --configuration phpunit.xml.nocoverage
|
||||
- "5.2"
|
||||
sudo: false
|
||||
before_script:
|
||||
- export PATH=~/.composer/vendor/bin/:$PATH
|
||||
- mysql -uroot -e "CREATE DATABASE test;"
|
||||
- if [ $TRAVIS_PHP_VERSION != "5.2" ] ; then composer install --dev --no-interaction ; fi
|
||||
- ./scripts/generate-mo --quiet
|
||||
script:
|
||||
- if [ $TRAVIS_PHP_VERSION != "5.2" ] ; then ./vendor/bin/phpunit --configuration phpunit.xml.nocoverage ; else phpunit --configuration phpunit.xml.nocoverage ; fi
|
||||
- git ls-files | grep '\.php$' | xargs -n1 php -l
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.composer/cache/
|
||||
|
||||
137
ChangeLog
137
ChangeLog
@ -1,7 +1,140 @@
|
||||
phpMyAdmin - ChangeLog
|
||||
======================
|
||||
|
||||
4.0.10.0 (not yet released)
|
||||
4.0.10.20 (2017-03-28)
|
||||
- issue #12881 Fix database search when locale is not 'en'
|
||||
- issue [security] Possible to bypass $cfg['Servers'][$i]['AllowNoPassword'], see PMASA-2017-08
|
||||
|
||||
4.0.10.19 (2017-01-23)
|
||||
- issue [security] Multiple vulnerabilities in setup script, see PMASA-2016-44.
|
||||
- issue [security] Open redirect, see PMASA-2017-1.
|
||||
- issue [security] php-gettext code execution, see PMASA-2017-2.
|
||||
- issue [security] DOS vulnerabiltiy in table editing, see PMASA-2017-3.
|
||||
- issue [security] CSS injection in themes, see PMASA-2017-4.
|
||||
- issue [security] SSRF in replication, see PMASA-2017-6.
|
||||
- issue [security] DOS in replication status, see PMASA-2017-7.
|
||||
|
||||
4.0.10.18 (2016-11-24)
|
||||
- issue #12485 Do not show warning about short blowfish_secret if none is set
|
||||
- issue [security] Open redirection issue, see PMASA-2016-57
|
||||
- issue [security] Unsafe generation of $cfg['blowfish_secret'], see PMASA-2016-58
|
||||
- issue [security] phpMyAdmin's phpinfo functionality is removed, see PMASA-2016-59
|
||||
- issue [security] AllowRoot and allow/deny rule bypass with specially-crafted username, see PMASA-2016-60
|
||||
- issue [security] Username matching weaknesses with allow/deny rules, see PMASA-2016-61
|
||||
- issue [security] Full path disclosure (FPD) weaknesses, see PMASA-2016-63
|
||||
- issue [security] Multiple cross-site scripting (XSS) weaknesses, see PMASA-2016-64
|
||||
- issue [security] Multiple denial-of-service (DOS) vulnerabilities, see PMASA-2016-65
|
||||
- issue [security] Possible to bypass white-list protection for URL redirection, see PMASA-2016-66
|
||||
- issue [security] Multiple SQL injection vulnerabilities, see PMASA-2016-69
|
||||
- issue [security] Incorrect serialized string parsing, see PMASA-2016-70
|
||||
- issue [security] CSRF token not stripped from the URL, see PMASA-2016-71
|
||||
|
||||
4.0.10.17 (2016-08-16)
|
||||
- issue [security] Weaknesses with cookie encryption, see PMASA-2016-29
|
||||
- issue [security] Improve session cookie code for openid.php and signon.php example files
|
||||
- issue [security] Full path disclosure in openid.php and signon.php example files
|
||||
- issue [security] Multiple XSS vulnerabilities, see PMASA-2016-30
|
||||
- issue [security] Unsafe generation of BlowfishSecret (when not supplied by the user)
|
||||
- issue [security] Referrer leak when phpinfo is enabled
|
||||
- issue [security] PHP code injection, see PMASA-2016-32
|
||||
- issue [security] Full path disclosure, see PMASA-2016-33
|
||||
- issue [security] SQL injection attack, see PMASA-2016-34
|
||||
- issue [security] Local file exposure through LOAD DATA LOCAL INFILE, see PMASA-2016-35
|
||||
- issue [security] Local file exposure through symlinks with UploadDir, see PMASA-2016-36
|
||||
- issue [security] Path traversal with SaveDir and UploadDir, see PMASA-2016-37
|
||||
- issue [security] Denial-of-service attack through transformation feature, see PMASA-2016-41
|
||||
- issue [security] SQL injection vulnerability as control user, see PMASA-2016-42
|
||||
- issue [security] Verify data before unserializing, see PMASA-2016-43
|
||||
- issue [security] Use HTTPS for wiki links
|
||||
- issue Remove Swekey support
|
||||
- issue [security] Denial-of-service attack with $cfg['AllowArbitraryServer'] = true and persistent connections, see PMASA-2016-45
|
||||
- issue [security] Improve SSL certificate handling
|
||||
- issue [security] Fix full path disclosure in debugging code
|
||||
- issue [security] Possible circumvention of IP-based allow/deny rules with IPv6 and proxy server, see PMASA-2016-47
|
||||
- issue [security] Detect if user is logged in, see PMASA-2016-48
|
||||
- issue [security] Bypass URL redirection protection, see PMASA-2016-49
|
||||
- issue [security] Referrer leak, see PMASA-2016-50
|
||||
- issue [security] Reflected File Download, see PMASA-2016-51
|
||||
- issue [security] ArbitraryServerRegexp bypass, see PMASA-2016-52
|
||||
- issue [security] Denial-of-service attack by entering long password, see PMASA-2016-53
|
||||
- issue [security] Remote code execution vulnerability when running as CGI, see PMASA-2016-54
|
||||
- issue [security] Denial-of-service attack when PHP uses dbase extension, see PMASA-2016-55
|
||||
- issue [security] Remove tode execution vulnerability when PHP uses dbase extension, see PMASA-2016-56
|
||||
- issue [security] Denial-of-service attack by using for loops, see PMASA-2016-46
|
||||
|
||||
4.0.10.16 (2016-06-23)
|
||||
- issue [security] User SQL queries can be revealed through URL GET parameters, see PMASA-2016-14
|
||||
- issue [security] Limit list of sites which can be passwd through url.php.
|
||||
- issue [security] BBCode injection in setup script, see PMASA-2016-17
|
||||
- issue [security] DOS attack vulnerability, see PMASA-2016-22
|
||||
- issue [security] Multiple full path disclosure vulnerabilities, see PMASA-2016-26
|
||||
- issue [security] XSS attack when checking database privileges, see PMASA-2016-21
|
||||
- issue [security] XSS attack when MySQL server is using a specific payload log_bin directive, see PMASA-2016-26
|
||||
- issue [security] XSS vulnerabilities in Transformation feature, PMASA-2016-28
|
||||
|
||||
4.0.10.15 (2016-02-29)
|
||||
- issue [security] Multiple XSS vulnerabilities, see PMASA-2016-11.
|
||||
|
||||
4.0.10.14 (2016-01-29)
|
||||
- issue #11891 Error with PMA 4.0.10.13 with PHP 5.2
|
||||
|
||||
4.0.10.13 (2016-01-28)
|
||||
- issue [Security] Multiple full path disclosure vulnerabilities, see PMASA-2016-1
|
||||
- issue [Security] Unsafe generation of CSRF token, see PMASA-2016-2
|
||||
- issue [Security] Multiple XSS vulnerabilities, see PMASA-2016-3
|
||||
- issue [Security] Insecure password generation in JavaScript, see PMASA-2016-4
|
||||
- issue [Security] Unsafe comparison of CSRF token, see PMASA-2016-5
|
||||
|
||||
4.0.10.12 (2015-12-25)
|
||||
- issue [Security] Path disclosure, see PMASA-2015-6
|
||||
|
||||
4.0.10.11 (2015-09-23)
|
||||
- issue #11464 phpMyAdmin suggests upgrading to newer version not usable on that system
|
||||
|
||||
4.0.10.10 (2015-05-13)
|
||||
- bug #4899 [security] CSRF vulnerability in setup
|
||||
- bug #4900 [security] Vulnerability allowing Man-in-the-middle attack
|
||||
|
||||
4.0.10.9 (2015-03-04)
|
||||
- bug [security] Risk of BREACH attack, see PMASA-2015-1
|
||||
|
||||
4.0.10.8 (2015-01-07)
|
||||
- rfe #1588 recursive function too deep - operator change suggestion
|
||||
- rfe #1589 support early versions of PHP5.2 (register_shutdown_function)
|
||||
|
||||
4.0.10.7 (2014-12-03)
|
||||
- bug #4611 [security] DOS attack with long passwords
|
||||
|
||||
4.0.10.6 (2014-11-20)
|
||||
- bug #4578 [security] XSS vulnerability in table print view
|
||||
- bug #4579 [security] XSS vulnerability in zoom search page
|
||||
- bug #4594 [security] Path traversal in file inclusion of GIS factory
|
||||
- bug #4598 [security] XSS in multi submit
|
||||
- bug #4597 [security] XSS through pma_fontsize cookie
|
||||
|
||||
4.0.10.5 (2014-10-21)
|
||||
- bug #4562 [security] XSS in debug SQL output
|
||||
- bug #4563 [security] XSS in monitor query analyzer
|
||||
|
||||
4.0.10.4 (2014-10-01)
|
||||
- bug #4544 [security] XSS vulnerabilities in table search and table structure pages
|
||||
|
||||
4.0.10.3 (2014-09-13)
|
||||
- bug #4530 [security] DOM based XSS that results to a CSRF that creates a
|
||||
ROOT account in certain conditions
|
||||
|
||||
4.0.10.2 (2014-08-17)
|
||||
- bug #4501 [security] XSS in table browse page
|
||||
- bug #4502 [security] Self-XSS in enum value editor
|
||||
- bug #4503 [security] Self-XSSes in monitor
|
||||
- bug #4504 [security] Self-XSS in query charts
|
||||
- bug #4517 [security] XSS in relation view
|
||||
|
||||
4.0.10.1 (2014-07-17)
|
||||
- bug #4488 [security] XSS injection due to unescaped table name (triggers)
|
||||
- bug #4492 [security] XSS in AJAX confirmation messages
|
||||
|
||||
4.0.10.0 (2013-12-04)
|
||||
- bug #4150 Clicking database name in query window opens a new tab
|
||||
- bug #4141 Wrong page is shown after editing; also, do not show a modal
|
||||
dialog for multi-row edit
|
||||
@ -330,7 +463,7 @@ underscore
|
||||
- bug #3776 [cookies] Login without auth on second server
|
||||
|
||||
--- Older ChangeLogs can be found on our project website ---
|
||||
http://www.phpmyadmin.net/old-stuff/ChangeLogs/
|
||||
https://www.phpmyadmin.net/old-stuff/ChangeLogs/
|
||||
|
||||
# vim: et ts=4 sw=4 sts=4
|
||||
# vim: ft=changelog fenc=utf-8
|
||||
|
||||
10
README
10
README
@ -1,11 +1,11 @@
|
||||
phpMyAdmin - Readme
|
||||
===================
|
||||
|
||||
Version 4.0.10-dev
|
||||
Version 4.0.10.20
|
||||
|
||||
A set of PHP-scripts to manage MySQL over the web.
|
||||
|
||||
http://www.phpmyadmin.net/
|
||||
https://www.phpmyadmin.net/
|
||||
|
||||
Copyright
|
||||
---------
|
||||
@ -13,7 +13,7 @@ Copyright
|
||||
Copyright (C) 1998-2000
|
||||
Tobias Ratschiller <tobias_at_ratschiller.com>
|
||||
|
||||
Copyright (C) 2001-2013
|
||||
Copyright (C) 2001-2014
|
||||
Marc Delisle <marc_at_infomarc.info>
|
||||
Olivier Müller <om_at_omnis.ch>
|
||||
Robin Johnson <robbat2_at_users.sourceforge.net>
|
||||
@ -55,7 +55,7 @@ For a summary of features, please see the documentation in the doc folder.
|
||||
Download
|
||||
--------
|
||||
|
||||
You can get the newest version at http://www.phpmyadmin.net/.
|
||||
You can get the newest version at https://www.phpmyadmin.net/.
|
||||
|
||||
More Information
|
||||
----------------
|
||||
@ -65,7 +65,7 @@ Please see the documentation in the doc folder.
|
||||
Support
|
||||
-------
|
||||
|
||||
See reference about support forums under http://www.phpmyadmin.net/
|
||||
See reference about support forums under https://www.phpmyadmin.net/
|
||||
|
||||
|
||||
Enjoy!
|
||||
|
||||
@ -3,7 +3,7 @@ phpMyAdmin
|
||||
|
||||
A set of PHP-scripts to manage MySQL over the web.
|
||||
|
||||
http://www.phpmyadmin.net/
|
||||
https://www.phpmyadmin.net/
|
||||
|
||||
Status
|
||||
------
|
||||
@ -23,14 +23,14 @@ Translations:
|
||||
Download
|
||||
--------
|
||||
|
||||
You can get the newest version at http://www.phpmyadmin.net/.
|
||||
You can get the newest version at https://www.phpmyadmin.net/.
|
||||
|
||||
More Information
|
||||
----------------
|
||||
|
||||
Please see the documentation in the doc folder or at http://docs.phpmyadmin.net/.
|
||||
Please see the documentation in the doc folder or at https://docs.phpmyadmin.net/.
|
||||
|
||||
Support
|
||||
-------
|
||||
|
||||
See reference about support forums under http://www.phpmyadmin.net/
|
||||
See reference about support forums under https://www.phpmyadmin.net/
|
||||
|
||||
@ -52,15 +52,15 @@ $github_url = 'https://github.com/phpmyadmin/phpmyadmin/';
|
||||
|
||||
$replaces = array(
|
||||
'@(http://[./a-zA-Z0-9.-_-]*[/a-zA-Z0-9_])@'
|
||||
=> '<a href="\\1">\\1</a>',
|
||||
=> '<a href="./url.php?url=\\1">\\1</a>',
|
||||
|
||||
// sourceforge users
|
||||
'/([0-9]{4}-[0-9]{2}-[0-9]{2}) (.+[^ ]) +<(.*)@users.sourceforge.net>/i'
|
||||
=> '\\1 <a href="https://sourceforge.net/users/\\3/">\\2</a>',
|
||||
=> '\\1 <a href="./url.php?url=https://sourceforge.net/users/\\3/">\\2</a>',
|
||||
'/thanks to ([^\(\r\n]+) \(([-\w]+)\)/i'
|
||||
=> 'thanks to <a href="https://sourceforge.net/users/\\2/">\\1</a>',
|
||||
=> 'thanks to <a href="./url.php?url=https://sourceforge.net/users/\\2/">\\1</a>',
|
||||
'/thanks to ([^\(\r\n]+) -\s+([-\w]+)/i'
|
||||
=> 'thanks to <a href="https://sourceforge.net/users/\\2/">\\1</a>',
|
||||
=> 'thanks to <a href="./url.php?url=https://sourceforge.net/users/\\2/">\\1</a>',
|
||||
|
||||
// mail address
|
||||
'/([0-9]{4}-[0-9]{2}-[0-9]{2}) (.+[^ ]) +<(.*@.*)>/i'
|
||||
@ -68,55 +68,55 @@ $replaces = array(
|
||||
|
||||
// linking patches
|
||||
'/patch\s*#?([0-9]{6,})/i'
|
||||
=> '<a href="' . $tracker_url . '">patch #\\1</a>',
|
||||
=> '<a href="./url.php?url=' . $tracker_url . '">patch #\\1</a>',
|
||||
|
||||
// linking RFE
|
||||
'/(?:rfe|feature)\s*#?([0-9]{6,})/i'
|
||||
=> '<a href="https://sourceforge.net/support/tracker.php?aid=\\1">RFE #\\1</a>',
|
||||
=> '<a href="./url.php?url=https://sourceforge.net/support/tracker.php?aid=\\1">RFE #\\1</a>',
|
||||
|
||||
// linking files
|
||||
'/(\s+)([\\/a-z_0-9\.]+\.(?:php3?|html|pl|js|sh))/i'
|
||||
=> '\\1<a href="' . $github_url . 'commits/HEAD/\\2">\\2</a>',
|
||||
=> '\\1<a href="./url.php?url=' . $github_url . 'commits/HEAD/\\2">\\2</a>',
|
||||
|
||||
// FAQ entries
|
||||
'/FAQ ([0-9]+)\.([0-9a-z]+)/i'
|
||||
=> '<a href="http://docs.phpmyadmin.net/en/latest/faq.html#faq\\1-\\2">FAQ \\1.\\2</a>',
|
||||
=> '<a href="./url.php?url=https://docs.phpmyadmin.net/en/latest/faq.html#faq\\1-\\2">FAQ \\1.\\2</a>',
|
||||
|
||||
// linking bugs
|
||||
'/bug\s*#?([0-9]{6,})/i'
|
||||
=> '<a href="https://sourceforge.net/support/tracker.php?aid=\\1">bug #\\1</a>',
|
||||
=> '<a href="./url.php?url=https://sourceforge.net/support/tracker.php?aid=\\1">bug #\\1</a>',
|
||||
|
||||
// all other 6+ digit numbers are treated as bugs
|
||||
'/(?<!bug|RFE|patch) #?([0-9]{6,})/i'
|
||||
=> '<a href="' . $tracker_url . '">bug #\\1</a>',
|
||||
=> '<a href="./url.php?url=' . $tracker_url . '">bug #\\1</a>',
|
||||
|
||||
// transitioned SF.net project bug/rfe/patch links
|
||||
// by the time we reach 6-digit numbers, we can probably retire the above links
|
||||
'/patch\s*#?([0-9]{4,5}) /i'
|
||||
=> '<a href="' . $tracker_url_patch . '">patch #\\1</a> ',
|
||||
=> '<a href="./url.php?url=' . $tracker_url_patch . '">patch #\\1</a> ',
|
||||
'/(?:rfe|feature)\s*#?([0-9]{4,5}) /i'
|
||||
=> '<a href="' . $tracker_url_rfe . '">RFE #\\1</a> ',
|
||||
=> '<a href="./url.php?url=' . $tracker_url_rfe . '">RFE #\\1</a> ',
|
||||
'/bug\s*#?([0-9]{4,5}) /i'
|
||||
=> '<a href="' . $tracker_url_bug . '">bug #\\1</a> ',
|
||||
=> '<a href="./url.php?url=' . $tracker_url_bug . '">bug #\\1</a> ',
|
||||
'/(?<!bug|RFE|patch) #?([0-9]{4,5}) /i'
|
||||
=> '<a href="' . $tracker_url_bug . '">bug #\\1</a> ',
|
||||
=> '<a href="./url.php?url=' . $tracker_url_bug . '">bug #\\1</a> ',
|
||||
|
||||
// CVE/CAN entries
|
||||
'/((CAN|CVE)-[0-9]+-[0-9]+)/'
|
||||
=> '<a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=\\1">\\1</a>',
|
||||
=> '<a href="./url.php?url=http://cve.mitre.org/cgi-bin/cvename.cgi?name=\\1">\\1</a>',
|
||||
|
||||
// PMASAentries
|
||||
'/(PMASA-[0-9]+-[0-9]+)/'
|
||||
=> '<a href="http://www.phpmyadmin.net/home_page/security/\\1.php">\\1</a>',
|
||||
=> '<a href="./url.php?url=https://www.phpmyadmin.net/security/\\1/">\\1</a>',
|
||||
|
||||
// Highlight releases (with links)
|
||||
'/([0-9]+)\.([0-9]+)\.([0-9]+)\.0 (\([0-9-]+\))/'
|
||||
=> '<a name="\\1_\\2_\\3"></a>'
|
||||
. '<a href="' . $github_url . 'commits/RELEASE_\\1_\\2_\\3">'
|
||||
. '<a href="./url.php?url=' . $github_url . 'commits/RELEASE_\\1_\\2_\\3">'
|
||||
. '\\1.\\2.\\3.0 \\4</a>',
|
||||
'/([0-9]+)\.([0-9]+)\.([0-9]+)\.([1-9][0-9]*) (\([0-9-]+\))/'
|
||||
=> '<a name="\\1_\\2_\\3_\\4"></a>'
|
||||
. '<a href="' . $github_url . 'commits/RELEASE_\\1_\\2_\\3_\\4">'
|
||||
. '<a href="./url.php?url=' . $github_url . 'commits/RELEASE_\\1_\\2_\\3_\\4">'
|
||||
. '\\1.\\2.\\3.\\4 \\5</a>',
|
||||
|
||||
// Highlight releases (not linkable)
|
||||
@ -146,6 +146,7 @@ echo '</pre>';
|
||||
var links = document.getElementsByTagName("a");
|
||||
for(var i = 0; i < links.length; i++) {
|
||||
links[i].target = "_blank";
|
||||
links[i].rel = "noopener noreferrer";
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@ -3,22 +3,27 @@
|
||||
"type": "application",
|
||||
"description": "MySQL web administration tool",
|
||||
"keywords": ["phpmyadmin","mysql","web"],
|
||||
"homepage": "http://www.phpmyadmin.net/",
|
||||
"homepage": "https://www.phpmyadmin.net/",
|
||||
"license": "GPL-2.0+",
|
||||
"authors": [
|
||||
{
|
||||
"name": "The phpMyAdmin Team",
|
||||
"email": "phpmyadmin-devel@lists.sourceforge.net",
|
||||
"homepage": "http://www.phpmyadmin.net/home_page/team.php"
|
||||
"homepage": "https://www.phpmyadmin.net/team/"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://sourceforge.net/p/phpmyadmin/discussion/Help",
|
||||
"issues": "https://sourceforge.net/p/phpmyadmin/bugs/",
|
||||
"wiki": "http://wiki.phpmyadmin.net/",
|
||||
"wiki": "https://wiki.phpmyadmin.net/",
|
||||
"source": "https://github.com/phpmyadmin/phpmyadmin"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"satooshi/php-coveralls": ">=0.6",
|
||||
"phpunit/phpunit": "<4.2",
|
||||
"phpunit/phpunit-selenium": ">=1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,14 +5,14 @@
|
||||
* manual configuration. For easier setup you can use setup/
|
||||
*
|
||||
* All directives are explained in documentation in the doc/ folder
|
||||
* or at <http://docs.phpmyadmin.net/>.
|
||||
* or at <https://docs.phpmyadmin.net/>.
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is needed for cookie based authentication to encrypt password in
|
||||
* cookie
|
||||
* cookie. Needs to be 32 chars long.
|
||||
*/
|
||||
$cfg['blowfish_secret'] = 'a8b7c6d'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */
|
||||
|
||||
@ -58,8 +58,6 @@ $cfg['Servers'][$i]['AllowNoPassword'] = false;
|
||||
// $cfg['Servers'][$i]['designer_coords'] = 'pma__designer_coords';
|
||||
// $cfg['Servers'][$i]['userconfig'] = 'pma__userconfig';
|
||||
// $cfg['Servers'][$i]['recent'] = 'pma__recent';
|
||||
/* Contrib / Swekey authentication */
|
||||
// $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey-pma.conf';
|
||||
|
||||
/*
|
||||
* End of servers configuration
|
||||
@ -136,6 +134,6 @@ $cfg['SaveDir'] = '';
|
||||
|
||||
/*
|
||||
* You can find more configuration options in the documentation
|
||||
* in the doc/ folder or at <http://docs.phpmyadmin.net/>.
|
||||
* in the doc/ folder or at <https://docs.phpmyadmin.net/>.
|
||||
*/
|
||||
?>
|
||||
|
||||
@ -49,7 +49,7 @@ copyright = u'2012 - 2013, The phpMyAdmin devel team'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '4.0.10-dev'
|
||||
version = '4.0.10.20'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = version
|
||||
|
||||
|
||||
@ -321,15 +321,6 @@ Server connection settings
|
||||
"phpMyAdmin " and either :config:option:`$cfg['Servers'][$i]['verbose']` or
|
||||
:config:option:`$cfg['Servers'][$i]['host']` will be used.
|
||||
|
||||
.. _servers_auth_swekey_config:
|
||||
.. config:option:: $cfg['Servers'][$i]['auth_swekey_config']
|
||||
|
||||
:type: string
|
||||
:default: ``''``
|
||||
|
||||
The name of the file containing :ref:`swekey` ids and login names for hardware
|
||||
authentication. Leave empty to deactivate this feature.
|
||||
|
||||
.. _servers_user:
|
||||
.. config:option:: $cfg['Servers'][$i]['user']
|
||||
|
||||
@ -1195,11 +1186,18 @@ Cookie authentication options
|
||||
:type: string
|
||||
:default: ``''``
|
||||
|
||||
The "cookie" auth\_type uses blowfish algorithm to encrypt the
|
||||
password. If you are using the "cookie" auth\_type, enter here a
|
||||
random passphrase of your choice. It will be used internally by the
|
||||
blowfish algorithm: you won’t be prompted for this passphrase. There
|
||||
is no maximum length for this secret.
|
||||
The "cookie" auth\_type uses AES algorithm to encrypt the password. If you
|
||||
are using the "cookie" auth\_type, enter here a random passphrase of your
|
||||
choice. It will be used internally by the AES algorithm: you won’t be
|
||||
prompted for this passphrase.
|
||||
|
||||
The secret should be 32 characters long. Using shorter will lead to weaker security
|
||||
of encrypted cookies, using longer will cause no harm.
|
||||
|
||||
.. note::
|
||||
|
||||
The configuration is called blowfish_secret for historical reasons as
|
||||
Blowfish algorithm was originally used to do the encryption.
|
||||
|
||||
.. versionchanged:: 3.1.0
|
||||
Since version 3.1.0 phpMyAdmin can generate this on the fly, but it
|
||||
@ -1412,11 +1410,6 @@ Main panel
|
||||
You can additionally hide more information by using
|
||||
:config:option:`$cfg['Servers'][$i]['verbose']`.
|
||||
|
||||
.. config:option:: $cfg['ShowPhpInfo']
|
||||
|
||||
:type: boolean
|
||||
:default: false
|
||||
|
||||
.. config:option:: $cfg['ShowChgPassword']
|
||||
|
||||
:type: boolean
|
||||
@ -1427,18 +1420,11 @@ Main panel
|
||||
:type: boolean
|
||||
:default: true
|
||||
|
||||
Defines whether to display the :guilabel:`PHP information` and
|
||||
Defines whether to display the
|
||||
:guilabel:`Change password` links and form for creating database or not at
|
||||
the starting main (right) frame. This setting does not check MySQL commands
|
||||
entered directly.
|
||||
|
||||
Please note that to block the usage of ``phpinfo()`` in scripts, you have to
|
||||
put this in your :file:`php.ini`:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
disable_functions = phpinfo()
|
||||
|
||||
Also note that enabling the :guilabel:`Change password` link has no effect
|
||||
with config authentication mode: because of the hard coded password value
|
||||
in the configuration file, end users can't be allowed to change their
|
||||
|
||||
@ -9,4 +9,4 @@ to make phpMyAdmin a useful tool.
|
||||
|
||||
You can check out all the possibilities to contribute in the
|
||||
`contribute section on our website
|
||||
<http://www.phpmyadmin.net/home_page/improve.php>`_.
|
||||
<https://www.phpmyadmin.net/contribute/>`_.
|
||||
|
||||
10
doc/faq.rst
10
doc/faq.rst
@ -4,7 +4,7 @@ FAQ - Frequently Asked Questions
|
||||
================================
|
||||
|
||||
Please have a look at our `Link section
|
||||
<http://www.phpmyadmin.net/home_page/docs.php>`_ on the official
|
||||
<https://www.phpmyadmin.net/home_page/docs.php>`_ on the official
|
||||
phpMyAdmin homepage for in-depth coverage of phpMyAdmin's features and
|
||||
or interface.
|
||||
|
||||
@ -904,7 +904,7 @@ just put your own input-elements inside. If you use a custom submit
|
||||
input field, the form will submit itself to the displaying page again,
|
||||
where you can validate the $HTTP\_POST\_VARS in a transformation. For
|
||||
a tutorial on how to effectively use transformations, see our `Link
|
||||
section <http://www.phpmyadmin.net/home_page/docs.php>`_ on the
|
||||
section <https://www.phpmyadmin.net/home_page/docs.php>`_ on the
|
||||
official phpMyAdmin-homepage.
|
||||
|
||||
.. _faq3_9:
|
||||
@ -1931,7 +1931,7 @@ Translations are very welcome and all you need to have are the
|
||||
language skills. The easiest way is to use our `online translation
|
||||
service <https://l10n.cihar.com/projects/phpmyadmin/>`_. You can check
|
||||
out all the possibilities to translate in the `translate section on
|
||||
our website <http://www.phpmyadmin.net/home_page/translate.php>`_.
|
||||
our website <https://www.phpmyadmin.net/home_page/translate.php>`_.
|
||||
|
||||
.. _faq7_3:
|
||||
|
||||
@ -1941,7 +1941,7 @@ our website <http://www.phpmyadmin.net/home_page/translate.php>`_.
|
||||
We welcome every contribution to the development of phpMyAdmin. You
|
||||
can check out all the possibilities to contribute in the `contribute
|
||||
section on our website
|
||||
<http://www.phpmyadmin.net/home_page/improve.php>`_.
|
||||
<https://www.phpmyadmin.net/home_page/improve.php>`_.
|
||||
|
||||
.. seealso:: :ref:`developers`
|
||||
|
||||
@ -1955,7 +1955,7 @@ Security
|
||||
8.1 Where can I get information about the security alerts issued for phpMyAdmin?
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Please refer to <http://www.phpmyadmin.net/home_page/security.php>.
|
||||
Please refer to <https://www.phpmyadmin.net/home_page/security.php>.
|
||||
|
||||
.. _faq8_2:
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ Currently phpMyAdmin can:
|
||||
* create, edit, call, export and drop stored procedures and functions
|
||||
* create, edit, export and drop events and triggers
|
||||
* communicate in `62 different languages
|
||||
<http://www.phpmyadmin.net/home_page/translations.php>`_
|
||||
<https://www.phpmyadmin.net/home_page/translations.php>`_
|
||||
|
||||
|
||||
A word about users
|
||||
|
||||
@ -8,11 +8,11 @@ The definitive guide to using phpMyAdmin is the book Mastering phpMyAdmin for
|
||||
Effective MySQL Management by Marc Delisle. You can get information on that
|
||||
book and other officially endorsed `books at the phpMyAdmin site`_.
|
||||
|
||||
.. _books at the phpMyAdmin site: http://www.phpmyadmin.net/home_page/docs.php?books
|
||||
.. _books at the phpMyAdmin site: https://www.phpmyadmin.net/home_page/docs.php?books
|
||||
|
||||
Tutorials
|
||||
---------
|
||||
|
||||
Third party tutorials and articles are listed on our `wiki page`_.
|
||||
|
||||
.. _wiki page: http://wiki.phpmyadmin.net/pma/Articles
|
||||
.. _wiki page: https://wiki.phpmyadmin.net/pma/Articles
|
||||
|
||||
@ -60,7 +60,8 @@ simple configuration may look like this:
|
||||
|
||||
|
||||
<?php
|
||||
$cfg['blowfish_secret'] = 'ba17c1ec07d65003'; // use here a value of your choice
|
||||
// use here a value of your choice at least 32 chars long
|
||||
$cfg['blowfish_secret'] = '1{dd0`<Q),5XP_:R9UK%%8\"EEcyH#{o';
|
||||
|
||||
$i=0;
|
||||
$i++;
|
||||
@ -91,51 +92,14 @@ For a full explanation of possible configuration values, see the
|
||||
Using Setup script
|
||||
------------------
|
||||
|
||||
Instead of manually editing :file:`config.inc.php`, you can use the `Setup
|
||||
Script <setup/>`_. First you must manually create a folder ``config``
|
||||
in the phpMyAdmin directory. This is a security measure. On a
|
||||
Linux/Unix system you can use the following commands:
|
||||
Instead of manually editing :file:`config.inc.php`, you can use phpMyAdmin's
|
||||
setup feature. The file can be generated using the setup and you can download it
|
||||
for upload to the server.
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
|
||||
cd phpMyAdmin
|
||||
mkdir config # create directory for saving
|
||||
chmod o+rw config # give it world writable permissions
|
||||
|
||||
And to edit an existing configuration, copy it over first:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
|
||||
cp config.inc.php config/ # copy current configuration for editing
|
||||
chmod o+w config/config.inc.php # give it world writable permissions
|
||||
|
||||
On other platforms, simply create the folder and ensure that your web
|
||||
server has read and write access to it. :ref:`faq1_26` can help with
|
||||
this.
|
||||
|
||||
Next, open ``setup/`` in your browser. If you have an existing configuration,
|
||||
use the ``Load`` button to bring its content inside the setup panel.
|
||||
Note that **changes are not saved to disk until explicitly choose ``Save``**
|
||||
from the *Configuration* area of the screen. Normally the script saves the new
|
||||
:file:`config.inc.php` to the ``config/`` directory, but if the webserver does
|
||||
not have the proper permissions you may see the error "Cannot load or
|
||||
save configuration." Ensure that the ``config/`` directory exists and
|
||||
has the proper permissions - or use the ``Download`` link to save the
|
||||
config file locally and upload it (via FTP or some similar means) to the
|
||||
proper location.
|
||||
|
||||
Once the file has been saved, it must be moved out of the ``config/``
|
||||
directory and the permissions must be reset, again as a security
|
||||
measure:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
|
||||
mv config/config.inc.php . # move file to current directory
|
||||
chmod o-rw config.inc.php # remove world read and write permissions
|
||||
rm -rf config # remove not needed directory
|
||||
Next, open your browser and visit the location where you installed phpMyAdmin,
|
||||
with the ``/setup`` suffix. The changes are not saved to the server, you need to
|
||||
use the :guilabel:`Download` button to save them to your computer and then upload
|
||||
to the server.
|
||||
|
||||
Now the file is ready to be used. You can choose to review or edit the
|
||||
file with your favorite editor, if you prefer to set some advanced
|
||||
@ -377,35 +341,6 @@ Config authentication mode
|
||||
of which are beyond the scope of this manual but easily searchable
|
||||
with Google).
|
||||
|
||||
.. index:: pair: Swekey; Authentication mode
|
||||
|
||||
.. _swekey:
|
||||
|
||||
Swekey authentication mode
|
||||
--------------------------
|
||||
|
||||
The Swekey is a low cost authentication USB key that can be used in
|
||||
web applications. When Swekey authentication is activated, phpMyAdmin
|
||||
requires the users's Swekey to be plugged before entering the login
|
||||
page (currently supported for cookie authentication mode only). Swekey
|
||||
Authentication is disabled by default. To enable it, add the following
|
||||
line to :file:`config.inc.php`:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey.conf';
|
||||
|
||||
You then have to create the ``swekey.conf`` file that will associate
|
||||
each user with their Swekey Id. It is important to place this file
|
||||
outside of your web server's document root (in the example, it is
|
||||
located in ``/etc``). A self documented sample file is provided in the
|
||||
``examples`` directory. Feel free to use it with your own users'
|
||||
information. If you want to purchase a Swekey please visit
|
||||
`http://phpmyadmin.net/auth\_key <http://phpmyadmin.net/auth_key>`_
|
||||
since this link provides funding for phpMyAdmin.
|
||||
|
||||
.. seealso:: :config:option:`$cfg['Servers'][$i]['auth_swekey_config']`
|
||||
|
||||
|
||||
Securing your phpMyAdmin installation
|
||||
+++++++++++++++++++++++++++++++++++++
|
||||
|
||||
@ -29,7 +29,7 @@ options, you can consult your *<www.your-host.com>/<your-install-
|
||||
dir>/transformation\_overview.php* installation.
|
||||
|
||||
For a tutorial on how to effectively use transformations, see our
|
||||
`Link section <http://www.phpmyadmin.net/home_page/docs.php>`_ on the
|
||||
`Link section <https://www.phpmyadmin.net/home_page/docs.php>`_ on the
|
||||
official phpMyAdmin homepage.
|
||||
|
||||
.. _transformationshowto:
|
||||
|
||||
@ -61,12 +61,22 @@ echo $contents;
|
||||
<?php
|
||||
}
|
||||
|
||||
function die_error($e)
|
||||
{
|
||||
$contents = "<div class='relyingparty_results'>\n";
|
||||
$contents .= "<pre>" . htmlspecialchars($e->getMessage()) . "</pre>\n";
|
||||
$contents .= "</div class='relyingparty_results'>";
|
||||
show_page($contents);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
/* Need to have cookie visible from parent directory */
|
||||
session_set_cookie_params(0, '/', '', 0);
|
||||
session_set_cookie_params(0, '/', '', true, true);
|
||||
/* Create signon session */
|
||||
$session_name = 'SignonSession';
|
||||
session_name($session_name);
|
||||
session_start();
|
||||
@session_start();
|
||||
|
||||
// Determine realm and return_to
|
||||
$base = 'http';
|
||||
@ -96,9 +106,9 @@ OpenID: <input type="text" name="identifier" /><br />
|
||||
}
|
||||
|
||||
/* Grab identifier */
|
||||
if (isset($_POST['identifier'])) {
|
||||
if (isset($_POST['identifier']) && is_string($_POST['identifier'])) {
|
||||
$identifier = $_POST['identifier'];
|
||||
} else if (isset($_SESSION['identifier'])) {
|
||||
} else if (isset($_SESSION['identifier']) && is_string($_SESSION['identifier'])) {
|
||||
$identifier = $_SESSION['identifier'];
|
||||
} else {
|
||||
$identifier = null;
|
||||
@ -107,24 +117,16 @@ if (isset($_POST['identifier'])) {
|
||||
/* Create OpenID object */
|
||||
try {
|
||||
$o = new OpenID_RelyingParty($returnTo, $realm, $identifier);
|
||||
} catch (OpenID_Exception $e) {
|
||||
$contents = "<div class='relyingparty_results'>\n";
|
||||
$contents .= "<pre>" . $e->getMessage() . "</pre>\n";
|
||||
$contents .= "</div class='relyingparty_results'>";
|
||||
show_page($contents);
|
||||
exit;
|
||||
} catch (Exception $e) {
|
||||
die_error($e);
|
||||
}
|
||||
|
||||
/* Redirect to OpenID provider */
|
||||
if (isset($_POST['start'])) {
|
||||
try {
|
||||
$authRequest = $o->prepare();
|
||||
} catch (OpenID_Exception $e) {
|
||||
$contents = "<div class='relyingparty_results'>\n";
|
||||
$contents .= "<pre>" . $e->getMessage() . "</pre>\n";
|
||||
$contents .= "</div class='relyingparty_results'>";
|
||||
show_page($contents);
|
||||
exit;
|
||||
} catch (Exception $e) {
|
||||
die_error($e);
|
||||
}
|
||||
|
||||
$url = $authRequest->getAuthorizeURL();
|
||||
@ -141,7 +143,11 @@ if (isset($_POST['start'])) {
|
||||
}
|
||||
|
||||
/* Check reply */
|
||||
try {
|
||||
$message = new OpenID_Message($queryString, OpenID_Message::FORMAT_HTTP);
|
||||
} catch (Exception $e) {
|
||||
die_error($e);
|
||||
}
|
||||
|
||||
$id = $message->get('openid.claimed_id');
|
||||
|
||||
|
||||
@ -12,11 +12,11 @@
|
||||
*/
|
||||
|
||||
/* Need to have cookie visible from parent directory */
|
||||
session_set_cookie_params(0, '/', '', 0);
|
||||
session_set_cookie_params(0, '/', '', true, true);
|
||||
/* Create signon session */
|
||||
$session_name = 'SignonSession';
|
||||
session_name($session_name);
|
||||
session_start();
|
||||
@session_start();
|
||||
|
||||
/* Was data posted? */
|
||||
if (isset($_POST['user'])) {
|
||||
@ -29,7 +29,7 @@ if (isset($_POST['user'])) {
|
||||
$_SESSION['PMA_single_signon_cfgupdate'] = array('verbose' => 'Signon test');
|
||||
$id = session_id();
|
||||
/* Close that session */
|
||||
session_write_close();
|
||||
@session_write_close();
|
||||
/* Redirect to phpMyAdmin (should use absolute URL here!) */
|
||||
header('Location: ../index.php');
|
||||
} else {
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
# This is a typical file used to enable Swekey hardware authentication.
|
||||
#
|
||||
# To activate the Swekey authentication add the following line to your config.inc.php file.
|
||||
# $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey-pma.conf';
|
||||
# Then rename this file "swekey-pma.conf" and copy it to the /etc directory.
|
||||
# Add all the Swekey ids you want to grant access to in the file.
|
||||
# After each Swekey id put the corresponding user name.
|
||||
#
|
||||
# If you don't know the id of a Swekey just visit http://www.swekey.com?sel=support
|
||||
# while your Swekey is connected.
|
||||
#
|
||||
# If you need to purchase a Swekey please visit http://phpmyadmin.net/auth_key
|
||||
# since this link provides funding to PhpMyAdmin.
|
||||
#
|
||||
|
||||
0000000000000000000000000000763A:root
|
||||
000000000000000000000000000089E4:steve
|
||||
0000000000000000000000000000231E:scott
|
||||
|
||||
#
|
||||
# It is recommended to include the following lines to contact the
|
||||
# authentication servers in SSL mode.
|
||||
#
|
||||
|
||||
SERVER_CHECK=https://auth-check-ssl.musbe.net
|
||||
SERVER_RNDTOKEN=https://auth-rnd-gen-ssl.musbe.net
|
||||
SERVER_STATUS=https://auth-status-ssl.musbe.net
|
||||
|
||||
#
|
||||
# The path of the root certificate file used to ensure a secure
|
||||
# communication with the authentication servers in SSL mode.
|
||||
# If not specified, will use musbe-ca.crt found in your
|
||||
# phpMyAdmin/libraries/auth/swekey.
|
||||
#
|
||||
|
||||
#CA_FILE=/var/http-root/phpmyadmin/libraries/auth/swekey/musbe-ca.crt
|
||||
|
||||
#
|
||||
# If your server receives many login requests, you can enable the random
|
||||
# token caching to accelerate the authentication process.
|
||||
# Token caching is enabled by default.
|
||||
#
|
||||
|
||||
#ENABLE_TOKEN_CACHE=0
|
||||
@ -10,59 +10,18 @@
|
||||
define('PMA_MINIMUM_COMMON', true);
|
||||
require_once 'libraries/common.inc.php';
|
||||
|
||||
/* For chart exporting */
|
||||
if (isset($_REQUEST['filename']) && isset($_REQUEST['image'])) {
|
||||
$allowed = array(
|
||||
'image/png' => 'png',
|
||||
'image/svg+xml' => 'svg',
|
||||
);
|
||||
|
||||
/* Check whether MIME type is allowed */
|
||||
if (! isset($allowed[$_REQUEST['type']])) {
|
||||
PMA_fatalError(__('Invalid export type'));
|
||||
}
|
||||
|
||||
/*
|
||||
* Check file name to match mime type and not contain new lines
|
||||
* to prevent response splitting.
|
||||
*/
|
||||
$extension = $allowed[$_REQUEST['type']];
|
||||
$valid_match = '/^[^\n\r]*\.' . $extension . '$/';
|
||||
if (! preg_match($valid_match, $_REQUEST['filename'])) {
|
||||
if (! preg_match('/^[^\n\r]*$/', $_REQUEST['filename'])) {
|
||||
/* Filename is unsafe, discard it */
|
||||
$filename = 'download.' . $extension;
|
||||
} else {
|
||||
/* Add extension */
|
||||
$filename = $_REQUEST['filename'] . '.' . $extension;
|
||||
}
|
||||
} else {
|
||||
/* Filename from request should be safe here */
|
||||
$filename = $_REQUEST['filename'];
|
||||
}
|
||||
|
||||
/* Decode data */
|
||||
if ($extension != 'svg') {
|
||||
$data = substr($_REQUEST['image'], strpos($_REQUEST['image'], ',') + 1);
|
||||
$data = base64_decode($data);
|
||||
} else {
|
||||
$data = $_REQUEST['image'];
|
||||
}
|
||||
|
||||
/* Send download header */
|
||||
PMA_downloadHeader($filename, $_REQUEST['type'], strlen($data));
|
||||
|
||||
/* Send data */
|
||||
echo $data;
|
||||
|
||||
} else if (isset($_REQUEST['monitorconfig'])) {
|
||||
if (isset($_REQUEST['monitorconfig'])) {
|
||||
/* For monitor chart config export */
|
||||
PMA_downloadHeader('monitor.cfg', 'application/force-download');
|
||||
PMA_downloadHeader('monitor.cfg', 'application/json; charset=UTF-8');
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
|
||||
echo urldecode($_REQUEST['monitorconfig']);
|
||||
|
||||
} else if (isset($_REQUEST['import'])) {
|
||||
/* For monitor chart config import */
|
||||
header('Content-type: text/plain');
|
||||
header('Content-Type: application/json; charset=UTF-8');
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
|
||||
if (!file_exists($_FILES['file']['tmp_name'])) {
|
||||
exit();
|
||||
}
|
||||
|
||||
17
import.php
17
import.php
@ -6,6 +6,11 @@
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
/* Enable LOAD DATA LOCAL INFILE for LDI plugin */
|
||||
if (isset($_POST['format']) && $_POST['format'] == 'ldi') {
|
||||
define('PMA_ENABLE_LDI', 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the variables sent or posted to this script and a core script
|
||||
*/
|
||||
@ -338,6 +343,15 @@ if (! empty($local_import_file) && ! empty($cfg['UploadDir'])) {
|
||||
$import_file = PMA_Util::userDir($cfg['UploadDir'])
|
||||
. $local_import_file;
|
||||
|
||||
/*
|
||||
* Do not allow symlinks to avoid security issues
|
||||
* (user can create symlink to file he can not access,
|
||||
* but phpMyAdmin can).
|
||||
*/
|
||||
if (is_link($import_file)) {
|
||||
$import_file = 'none';
|
||||
}
|
||||
|
||||
} elseif (empty($import_file) || ! is_uploaded_file($import_file)) {
|
||||
$import_file = 'none';
|
||||
}
|
||||
@ -474,8 +488,9 @@ if ($GLOBALS['PMA_recoding_engine'] != PMA_CHARSET_NONE && isset($charset_of_fil
|
||||
|
||||
// Something to skip?
|
||||
if (! $error && isset($skip)) {
|
||||
$skip = intval($skip);
|
||||
$original_skip = $skip;
|
||||
while ($skip > 0) {
|
||||
while ($skip > 0 && ! $finished) {
|
||||
PMA_importGetNextChunk($skip < $read_limit ? $skip : $read_limit);
|
||||
// Disable read progresivity, otherwise we eat all memory!
|
||||
$read_multiply = 1;
|
||||
|
||||
43
index.php
43
index.php
@ -269,7 +269,7 @@ if ($server > 0 && $GLOBALS['cfg']['ShowServerInfo']) {
|
||||
echo ' </div>';
|
||||
}
|
||||
|
||||
if ($GLOBALS['cfg']['ShowServerInfo'] || $GLOBALS['cfg']['ShowPhpInfo']) {
|
||||
if ($GLOBALS['cfg']['ShowServerInfo']) {
|
||||
echo '<div class="group">';
|
||||
echo '<h2>' . __('Web server') . '</h2>';
|
||||
echo '<ul>';
|
||||
@ -300,15 +300,6 @@ if ($GLOBALS['cfg']['ShowServerInfo'] || $GLOBALS['cfg']['ShowPhpInfo']) {
|
||||
}
|
||||
}
|
||||
|
||||
if ($cfg['ShowPhpInfo']) {
|
||||
PMA_printListItem(
|
||||
__('Show PHP information'),
|
||||
'li_phpinfo',
|
||||
'phpinfo.php?' . $common_url_query,
|
||||
null,
|
||||
'_blank'
|
||||
);
|
||||
}
|
||||
echo ' </ul>';
|
||||
echo ' </div>';
|
||||
}
|
||||
@ -317,7 +308,7 @@ echo '<div class="group pmagroup">';
|
||||
echo '<h2>phpMyAdmin</h2>';
|
||||
echo '<ul>';
|
||||
$class = null;
|
||||
// We rely on CSP to allow access to http://www.phpmyadmin.net, but IE lacks
|
||||
// We rely on CSP to allow access to https://www.phpmyadmin.net, but IE lacks
|
||||
// support here and does not allow request to http once using https.
|
||||
if ($GLOBALS['cfg']['VersionCheck']
|
||||
&& (! $GLOBALS['PMA_Config']->get('is_https') || PMA_USR_BROWSER_AGENT != 'IE')
|
||||
@ -343,7 +334,7 @@ PMA_printListItem(
|
||||
PMA_printListItem(
|
||||
__('Wiki'),
|
||||
'li_pma_wiki',
|
||||
PMA_linkURL('http://wiki.phpmyadmin.net/'),
|
||||
PMA_linkURL('https://wiki.phpmyadmin.net/'),
|
||||
null,
|
||||
'_blank'
|
||||
);
|
||||
@ -352,21 +343,21 @@ PMA_printListItem(
|
||||
PMA_printListItem(
|
||||
__('Official Homepage'),
|
||||
'li_pma_homepage',
|
||||
PMA_linkURL('http://www.phpMyAdmin.net/'),
|
||||
PMA_linkURL('http://www.phpmyadmin.net/'),
|
||||
null,
|
||||
'_blank'
|
||||
);
|
||||
PMA_printListItem(
|
||||
__('Contribute'),
|
||||
'li_pma_contribute',
|
||||
PMA_linkURL('http://www.phpmyadmin.net/home_page/improve.php'),
|
||||
PMA_linkURL('https://www.phpmyadmin.net/home_page/improve.php'),
|
||||
null,
|
||||
'_blank'
|
||||
);
|
||||
PMA_printListItem(
|
||||
__('Get support'),
|
||||
'li_pma_support',
|
||||
PMA_linkURL('http://www.phpmyadmin.net/home_page/support.php'),
|
||||
PMA_linkURL('https://www.phpmyadmin.net/home_page/support.php'),
|
||||
null,
|
||||
'_blank'
|
||||
);
|
||||
@ -447,13 +438,22 @@ if ($GLOBALS['cfg']['LoginCookieStore'] != 0
|
||||
/**
|
||||
* Check if user does not have defined blowfish secret and it is being used.
|
||||
*/
|
||||
if (! empty($_SESSION['auto_blowfish_secret'])
|
||||
&& empty($GLOBALS['cfg']['blowfish_secret'])
|
||||
) {
|
||||
if (! empty($_SESSION['encryption_key'])) {
|
||||
if (empty($GLOBALS['cfg']['blowfish_secret'])) {
|
||||
trigger_error(
|
||||
__('The configuration file now needs a secret passphrase (blowfish_secret).'),
|
||||
__(
|
||||
'The configuration file now needs a secret passphrase (blowfish_secret).'
|
||||
),
|
||||
E_USER_WARNING
|
||||
);
|
||||
} elseif (strlen($GLOBALS['cfg']['blowfish_secret']) < 32) {
|
||||
trigger_error(
|
||||
__(
|
||||
'The secret passphrase in configuration (blowfish_secret) is too short.'
|
||||
),
|
||||
E_USER_WARNING
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -565,7 +565,7 @@ if (file_exists('libraries/language_stats.inc.php')) {
|
||||
&& $GLOBALS['language_stats'][$lang] < $cfg['TranslationWarningThreshold']
|
||||
) {
|
||||
trigger_error(
|
||||
'You are using an incomplete translation, please help to make it better by [a@http://www.phpmyadmin.net/home_page/improve.php#translate@_blank]contributing[/a].',
|
||||
'You are using an incomplete translation, please help to make it better by [a@https://www.phpmyadmin.net/home_page/improve.php#translate@_blank]contributing[/a].',
|
||||
E_USER_NOTICE
|
||||
);
|
||||
}
|
||||
@ -598,6 +598,9 @@ function PMA_printListItem($name, $id = null, $url = null, $mysql_help_page = nu
|
||||
echo '<a href="' . $url . '"';
|
||||
if (null !== $target) {
|
||||
echo ' target="' . $target . '"';
|
||||
if ($target == '_blank') {
|
||||
echo ' rel="noopener noreferrer"';
|
||||
}
|
||||
}
|
||||
if (null != $a_id) {
|
||||
echo ' id="' . $a_id .'"';
|
||||
|
||||
18
js/ajax.js
18
js/ajax.js
@ -711,12 +711,20 @@ AJAX.setUrlHash = (function (jQuery, window) {
|
||||
/**
|
||||
* Start initialisation
|
||||
*/
|
||||
if (window.location.hash.substring(0, 8) == '#PMAURL-') {
|
||||
var urlhash = window.location.hash;
|
||||
if (urlhash.substring(0, 8) == '#PMAURL-') {
|
||||
// We have a valid hash, let's redirect the user
|
||||
// to the page that it's pointing to
|
||||
window.location = window.location.hash.substring(
|
||||
window.location.hash.indexOf(':') + 1
|
||||
var colon_position = urlhash.indexOf(':');
|
||||
var questionmark_position = urlhash.indexOf('?');
|
||||
if (colon_position != -1 && questionmark_position != -1 && colon_position < questionmark_position) {
|
||||
var hash_url = urlhash.substring(colon_position + 1, questionmark_position);
|
||||
if (PMA_gotoWhitelist.indexOf(hash_url) != -1) {
|
||||
window.location = urlhash.substring(
|
||||
colon_position + 1
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We don't have a valid hash, so we'll set it up
|
||||
// when the page finishes loading
|
||||
@ -801,8 +809,8 @@ $(document).ajaxError(function(event, request, settings){
|
||||
PMA_ajaxShowMessage(
|
||||
'<div class="error">'
|
||||
+ PMA_messages['strErrorProcessingRequest']
|
||||
+ '<div>' + errorCode + '</div>'
|
||||
+ '<div>' + errorText + '</div>'
|
||||
+ '<div>' + escapeHtml(errorCode) + '</div>'
|
||||
+ '<div>' + escapeHtml(errorText) + '</div>'
|
||||
+ '</div>',
|
||||
false
|
||||
);
|
||||
|
||||
@ -556,8 +556,8 @@ AJAX.registerOnload('config.js', function() {
|
||||
var tab_check_fnc = function() {
|
||||
if (location.hash != prev_hash) {
|
||||
prev_hash = location.hash;
|
||||
if (location.hash.match(/^#tab_.+/) && $('#' + location.hash.substr(5)).length) {
|
||||
setTab(location.hash.substr(5));
|
||||
if (prev_hash.match(/^#tab_[a-zA-Z0-9_]+$/) && $('#' + prev_hash.substr(5)).length) {
|
||||
setTab(prev_hash.substr(5));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -77,14 +77,31 @@ function suggestPassword(passwd_form)
|
||||
// restrict the password to just letters and numbers to avoid problems:
|
||||
// "editors and viewers regard the password as multiple words and
|
||||
// things like double click no longer work"
|
||||
var pwchars = "abcdefhjmnpqrstuvwxyz23456789ABCDEFGHJKLMNPQRSTUVWYXZ";
|
||||
var pwchars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWYXZ";
|
||||
var passwordlength = 16; // do we want that to be dynamic? no, keep it simple :)
|
||||
var passwd = passwd_form.generated_pw;
|
||||
var randomWords = new Int32Array(passwordlength);
|
||||
|
||||
passwd.value = '';
|
||||
|
||||
for (var i = 0; i < passwordlength; i++ ) {
|
||||
passwd.value += pwchars.charAt( Math.floor( Math.random() * pwchars.length ) );
|
||||
// First we're going to try to use a built-in CSPRNG
|
||||
if (window.crypto && window.crypto.getRandomValues) {
|
||||
window.crypto.getRandomValues(randomWords);
|
||||
}
|
||||
// Because of course IE calls it msCrypto instead of being standard
|
||||
else if (window.msCrypto && window.msCrypto.getRandomValues) {
|
||||
window.msCrypto.getRandomValues(randomWords);
|
||||
} else {
|
||||
// Fallback to Math.random
|
||||
for (var i = 0; i < passwordlength; i++) {
|
||||
randomWords[i] = Math.floor(Math.random() * pwchars.length);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < passwordlength; i++) {
|
||||
passwd.value += pwchars.charAt(Math.abs(randomWords[i]) % pwchars.length);
|
||||
}
|
||||
|
||||
passwd_form.text_pma_pw.value = passwd.value;
|
||||
passwd_form.text_pma_pw2.value = passwd.value;
|
||||
return true;
|
||||
@ -1358,7 +1375,7 @@ AJAX.registerOnload('functions.js', function() {
|
||||
var $inner_sql = $(this).parent().prev().find('.inner_sql');
|
||||
var old_text = $inner_sql.html();
|
||||
|
||||
var new_content = "<textarea name=\"sql_query_edit\" id=\"sql_query_edit\">" + sql_query + "</textarea>\n";
|
||||
var new_content = "<textarea name=\"sql_query_edit\" id=\"sql_query_edit\">" + escapeHtml(sql_query) + "</textarea>\n";
|
||||
new_content += "<input type=\"submit\" id=\"sql_query_edit_save\" class=\"button btnSave\" value=\"" + PMA_messages['strGo'] + "\"/>\n";
|
||||
new_content += "<input type=\"button\" id=\"sql_query_edit_discard\" class=\"button btnDiscard\" value=\"" + PMA_messages['strCancel'] + "\"/>\n";
|
||||
var $editor_area = $('div#inline_editor');
|
||||
@ -2550,7 +2567,7 @@ AJAX.registerOnload('functions.js', function() {
|
||||
} else {
|
||||
var title = PMA_messages['enum_columnVals'].replace(
|
||||
/%s/,
|
||||
'"' + decodeURIComponent(colname) + '"'
|
||||
'"' + escapeHtml(decodeURIComponent(colname)) + '"'
|
||||
);
|
||||
}
|
||||
// Get the values as a string
|
||||
@ -3178,7 +3195,16 @@ AJAX.registerOnload('functions.js', function() {
|
||||
* Load version information asynchronously.
|
||||
*/
|
||||
if ($('li.jsversioncheck').length > 0) {
|
||||
$.getJSON('version_check.php', {}, PMA_current_version);
|
||||
$.ajax({
|
||||
dataType: "json",
|
||||
url: 'version_check.php',
|
||||
method: "POST",
|
||||
data: {
|
||||
"server": PMA_commonParams.get('server'),
|
||||
"token": PMA_commonParams.get('token'),
|
||||
},
|
||||
success: PMA_current_version
|
||||
});
|
||||
}
|
||||
|
||||
if ($('#is_git_revision').length > 0) {
|
||||
@ -3368,7 +3394,7 @@ AJAX.registerOnload('functions.js', function() {
|
||||
var question = PMA_messages.strDropTableStrongWarning + ' ';
|
||||
question += $.sprintf(
|
||||
PMA_messages.strDoYouReally,
|
||||
'DROP TABLE ' + PMA_commonParams.get('table')
|
||||
'DROP TABLE ' + escapeHtml(PMA_commonParams.get('table'))
|
||||
);
|
||||
|
||||
$(this).PMA_confirm(question, $(this).attr('href'), function(url) {
|
||||
@ -3401,7 +3427,7 @@ AJAX.registerOnload('functions.js', function() {
|
||||
var question = PMA_messages.strTruncateTableStrongWarning + ' ';
|
||||
question += $.sprintf(
|
||||
PMA_messages.strDoYouReally,
|
||||
'TRUNCATE ' + PMA_commonParams.get('table')
|
||||
'TRUNCATE ' + escapeHtml(PMA_commonParams.get('table'))
|
||||
);
|
||||
$(this).PMA_confirm(question, $(this).attr('href'), function(url) {
|
||||
PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);
|
||||
|
||||
@ -101,15 +101,15 @@ function PMA_getImage(image, alternate, attributes) {
|
||||
}
|
||||
// set alt
|
||||
if (attributes.alt != undefined) {
|
||||
retval.attr('alt', attributes.alt);
|
||||
retval.attr('alt', escapeHtml(attributes.alt));
|
||||
} else {
|
||||
retval.attr('alt', alternate);
|
||||
retval.attr('alt', escapeHtml(alternate));
|
||||
}
|
||||
// set title
|
||||
if (attributes.title != undefined) {
|
||||
retval.attr('title', attributes.title);
|
||||
retval.attr('title', escapeHtml(attributes.title));
|
||||
} else {
|
||||
retval.attr('title', alternate);
|
||||
retval.attr('title', escapeHtml(alternate));
|
||||
}
|
||||
// set src
|
||||
var klass = image.replace('.gif', '').replace('.png', '');
|
||||
|
||||
@ -14,7 +14,8 @@ header('Content-Type: text/javascript; charset=UTF-8');
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
|
||||
|
||||
if (! empty($_GET['scripts']) && is_array($_GET['scripts'])) {
|
||||
foreach ($_GET['scripts'] as $script) {
|
||||
// Only up to 10 scripts as this is what we generate
|
||||
foreach (array_slice($_GET['scripts'], 0, 10) as $script) {
|
||||
// Sanitise filename
|
||||
$script_name = 'js';
|
||||
$path = explode("/", $script);
|
||||
|
||||
@ -996,7 +996,7 @@ AJAX.registerOnload('server_status_monitor.js', function() {
|
||||
label: $('#variableInput').val().replace(/_/g, " ")
|
||||
};
|
||||
newChart.series.push(newSeries);
|
||||
$('#seriesPreview').append('- ' + newSeries.label + str + '<br/>');
|
||||
$('#seriesPreview').append('- ' + escapeHtml(newSeries.label + str) + '<br/>');
|
||||
newChart.nodes.push(serie);
|
||||
$('#variableInput').val('');
|
||||
$('input[name="differentialValue"]').prop('checked', true);
|
||||
@ -1991,7 +1991,7 @@ AJAX.registerOnload('server_status_monitor.js', function() {
|
||||
case 'user_host':
|
||||
return value.replace(/(\[.*?\])+/g, '');
|
||||
}
|
||||
return value;
|
||||
return escapeHtml(value);
|
||||
};
|
||||
|
||||
for (var i = 0, l = rows.length; i < l; i++) {
|
||||
@ -2144,7 +2144,7 @@ AJAX.registerOnload('server_status_monitor.js', function() {
|
||||
for (var i = 0, l = data.explain.length; i < l; i++) {
|
||||
explain += '<div class="explain-' + i + '"' + (i>0? 'style="display:none;"' : '' ) + '>';
|
||||
$.each(data.explain[i], function(key, value) {
|
||||
value = (value == null)?'null':value;
|
||||
value = (value == null)?'null': escapeHtml(value);
|
||||
|
||||
if (key == 'type' && value.toLowerCase() == 'all') {
|
||||
value = '<span class="attention">' + value + '</span>';
|
||||
|
||||
@ -103,7 +103,7 @@ AJAX.registerOnload('sql.js', function() {
|
||||
// Delete row from SQL results
|
||||
$('a.delete_row.ajax').click(function (e) {
|
||||
e.preventDefault();
|
||||
var question = $.sprintf(PMA_messages['strDoYouReally'], $(this).closest('td').find('div').text());
|
||||
var question = $.sprintf(PMA_messages['strDoYouReally'], escapeHtml($(this).closest('td').find('div').text()));
|
||||
var $link = $(this);
|
||||
$link.PMA_confirm(question, $link.attr('href'), function (url) {
|
||||
$msgbox = PMA_ajaxShowMessage();
|
||||
|
||||
@ -201,7 +201,7 @@ function drawChart() {
|
||||
|
||||
var columnNames = [];
|
||||
$('select[name="chartXAxis"] option').each(function() {
|
||||
columnNames.push($(this).text());
|
||||
columnNames.push(escapeHtml($(this).text()));
|
||||
});
|
||||
try {
|
||||
currentChart = PMA_queryChart(chart_data, columnNames, currentSettings);
|
||||
@ -260,7 +260,7 @@ function PMA_queryChart(data, columnNames, settings) {
|
||||
},
|
||||
axes : {
|
||||
xaxis : {
|
||||
label : settings.xaxisLabel
|
||||
label : escapeHtml(settings.xaxisLabel)
|
||||
},
|
||||
yaxis : {
|
||||
label : settings.yaxisLabel
|
||||
|
||||
@ -144,6 +144,7 @@ AJAX.registerOnload('tbl_structure.js', function() {
|
||||
* @var curr_column_name String containing name of the field referred to by {@link curr_row}
|
||||
*/
|
||||
var curr_column_name = $curr_row.children('th').children('label').text();
|
||||
curr_column_name = escapeHtml(curr_column_name);
|
||||
/**
|
||||
* @var $after_field_item Corresponding entry in the 'After' field.
|
||||
*/
|
||||
|
||||
31
js/whitelist.php
Normal file
31
js/whitelist.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* Exporting of $goto_whitelist from PHP to Javascript
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
chdir('..');
|
||||
|
||||
// Send correct type:
|
||||
header('Content-Type: text/javascript; charset=UTF-8');
|
||||
|
||||
// Cache output in client - the nocache query parameter makes sure that this
|
||||
// file is reloaded when config changes
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
|
||||
|
||||
// Avoid loading the full common.inc.php because this would add many
|
||||
// non-js-compatible stuff like DOCTYPE
|
||||
define('PMA_MINIMUM_COMMON', true);
|
||||
require_once './libraries/common.inc.php';
|
||||
// Close session early as we won't write anything there
|
||||
session_write_close();
|
||||
|
||||
echo "var PMA_gotoWhitelist = new Array();\n";
|
||||
$i = -1;
|
||||
foreach ($GLOBALS['goto_whitelist'] as $one_whitelist) {
|
||||
$i++;
|
||||
echo 'PMA_gotoWhitelist[' . $i . ']="' . $one_whitelist . '";' . "\n";
|
||||
}
|
||||
?>
|
||||
@ -102,7 +102,7 @@ class PMA_Config
|
||||
*/
|
||||
function checkSystem()
|
||||
{
|
||||
$this->set('PMA_VERSION', '4.0.10-dev');
|
||||
$this->set('PMA_VERSION', '4.0.10.20');
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
@ -716,8 +716,6 @@ class PMA_Config
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 1);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'phpMyAdmin/' . PMA_VERSION);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
||||
@ -1293,7 +1291,7 @@ class PMA_Config
|
||||
$pma_absolute_uri .= '@';
|
||||
}
|
||||
// Add hostname
|
||||
$pma_absolute_uri .= $url['host'];
|
||||
$pma_absolute_uri .= urlencode($url['host']);
|
||||
// Add port, if it not the default one
|
||||
if (! empty($url['port'])
|
||||
&& (($url['scheme'] == 'http' && $url['port'] != 80)
|
||||
@ -1717,7 +1715,7 @@ class PMA_Config
|
||||
// for the case when there is no config file (this is supported)
|
||||
if (empty($current_size)) {
|
||||
if (isset($_COOKIE['pma_fontsize'])) {
|
||||
$current_size = $_COOKIE['pma_fontsize'];
|
||||
$current_size = htmlspecialchars($_COOKIE['pma_fontsize']);
|
||||
} else {
|
||||
$current_size = '82%';
|
||||
}
|
||||
|
||||
@ -203,7 +203,10 @@ class PMA_DbQbe
|
||||
// sets row count
|
||||
$rows = PMA_ifSetOr($_REQUEST['rows'], 0, 'numeric');
|
||||
$criteriaRowAdd = PMA_ifSetOr($_REQUEST['criteriaRowAdd'], 0, 'numeric');
|
||||
$this->_criteria_row_count = max($rows + $criteriaRowAdd, 0);
|
||||
$this->_criteria_row_count = min(
|
||||
max($rows + $criteriaRowAdd, 0),
|
||||
100
|
||||
);
|
||||
|
||||
$this->_criteriaColumnInsert = PMA_ifSetOr(
|
||||
$_REQUEST['criteriaColumnInsert'],
|
||||
|
||||
@ -277,7 +277,7 @@ class PMA_DbSearch
|
||||
// Gets the SQL statements
|
||||
$newsearchsqls = $this->_getSearchSqls($each_table);
|
||||
// Executes the "COUNT" statement
|
||||
$res_cnt = PMA_DBI_fetch_value($newsearchsqls['select_count']);
|
||||
$res_cnt = intval(PMA_DBI_fetch_value($newsearchsqls['select_count']));
|
||||
$num_search_result_total += $res_cnt;
|
||||
// Gets the result row's HTML for a table
|
||||
$html_output .= $this->_getResultsRow(
|
||||
@ -340,7 +340,8 @@ class PMA_DbSearch
|
||||
$browse_result_path = 'sql.php' . PMA_generate_common_url($this_url_params);
|
||||
$html_output .= '<td><a name="browse_search" href="'
|
||||
. $browse_result_path . '" onclick="loadResult(\''
|
||||
. $browse_result_path . '\',\'' . $each_table . '\',\''
|
||||
. $browse_result_path . '\',\''
|
||||
. PMA_escapeJsString(htmlspecialchars($each_table)) . '\',\''
|
||||
. PMA_generate_common_url($GLOBALS['db'], $each_table) . '\''
|
||||
. ');return false;" >'
|
||||
. __('Browse') . '</a></td>';
|
||||
@ -349,10 +350,10 @@ class PMA_DbSearch
|
||||
$html_output .= '<td><a name="delete_search" href="'
|
||||
. $delete_result_path . '" onclick="deleteResult(\''
|
||||
. $delete_result_path . '\' , \''
|
||||
. sprintf(
|
||||
. PMA_escapeJsString(sprintf(
|
||||
__('Delete the matches for the %s table?'),
|
||||
htmlspecialchars($each_table)
|
||||
)
|
||||
))
|
||||
. '\');return false;">'
|
||||
. __('Delete') . '</a></td>';
|
||||
} else {
|
||||
|
||||
@ -371,14 +371,18 @@ class PMA_Error extends PMA_Message
|
||||
* prevent path disclusore in error message,
|
||||
* and make users feel save to submit error reports
|
||||
*
|
||||
* @param string $dest path to be shorten
|
||||
* @param string $path path to be shorten
|
||||
*
|
||||
* @return string shortened path
|
||||
* @static
|
||||
*/
|
||||
static function relPath($dest)
|
||||
static function relPath($path)
|
||||
{
|
||||
$dest = realpath($dest);
|
||||
$dest = @realpath($path);
|
||||
|
||||
if ($dest === false) {
|
||||
return basename($path);
|
||||
}
|
||||
|
||||
if (substr(PHP_OS, 0, 3) == 'WIN') {
|
||||
$path_separator = '\\';
|
||||
|
||||
@ -428,6 +428,11 @@ class PMA_File
|
||||
$this->setName(
|
||||
PMA_Util::userDir($GLOBALS['cfg']['UploadDir']) . PMA_securePath($name)
|
||||
);
|
||||
if (is_link($this->getName())) {
|
||||
$this->_error_message = __('File is a symbolic link');
|
||||
$this->setName(null);
|
||||
return false;
|
||||
}
|
||||
if (! $this->isReadable()) {
|
||||
$this->_error_message = __('File could not be read');
|
||||
$this->setName(null);
|
||||
|
||||
@ -146,7 +146,16 @@ class PMA_Header
|
||||
*/
|
||||
private function _addDefaultScripts()
|
||||
{
|
||||
// Localised strings
|
||||
$params = array('lang' => $GLOBALS['lang']);
|
||||
if (isset($GLOBALS['db'])) {
|
||||
$params['db'] = $GLOBALS['db'];
|
||||
}
|
||||
|
||||
$this->_scripts->addFile('jquery/jquery-1.8.3.min.js');
|
||||
$this->_scripts->addFile(
|
||||
'whitelist.php' . PMA_generate_common_url($params), false, true
|
||||
);
|
||||
$this->_scripts->addFile('ajax.js');
|
||||
$this->_scripts->addFile('keyhandler.js');
|
||||
$this->_scripts->addFile('jquery/jquery-ui-1.9.2.custom.min.js');
|
||||
@ -169,11 +178,6 @@ class PMA_Header
|
||||
// Here would not be a good place to add CodeMirror because
|
||||
// the user preferences have not been merged at this point
|
||||
|
||||
// Localised strings
|
||||
$params = array('lang' => $GLOBALS['lang']);
|
||||
if (isset($GLOBALS['db'])) {
|
||||
$params['db'] = $GLOBALS['db'];
|
||||
}
|
||||
$this->_scripts->addFile('messages.php' . PMA_generate_common_url($params));
|
||||
// Append the theme id to this url to invalidate
|
||||
// the cache on a theme change. Though this might be
|
||||
@ -461,41 +465,56 @@ class PMA_Header
|
||||
'X-Frame-Options: DENY'
|
||||
);
|
||||
}
|
||||
header(
|
||||
"Content-Security-Policy: default-src 'self' "
|
||||
. $GLOBALS['cfg']['CSPAllow'] . ';'
|
||||
. "script-src 'self' 'unsafe-inline' 'unsafe-eval' "
|
||||
. $GLOBALS['cfg']['CSPAllow'] . ';'
|
||||
. ";"
|
||||
. "style-src 'self' 'unsafe-inline' "
|
||||
. $GLOBALS['cfg']['CSPAllow']
|
||||
. ";"
|
||||
. "referrer no-referrer;"
|
||||
. "img-src 'self' data: "
|
||||
. $GLOBALS['cfg']['CSPAllow']
|
||||
. ($https ? "" : $mapTilesUrls)
|
||||
. ";"
|
||||
);
|
||||
header(
|
||||
"X-Content-Security-Policy: default-src 'self' "
|
||||
. $GLOBALS['cfg']['CSPAllow'] . ';'
|
||||
. "options inline-script eval-script;"
|
||||
. "img-src 'self' data: "
|
||||
. "referrer no-referrer;"
|
||||
. $GLOBALS['cfg']['CSPAllow']
|
||||
. ($https ? "" : $mapTilesUrls)
|
||||
. ";"
|
||||
);
|
||||
if (PMA_USR_BROWSER_AGENT == 'SAFARI'
|
||||
&& PMA_USR_BROWSER_VER < '6.0.0'
|
||||
) {
|
||||
header(
|
||||
"X-WebKit-CSP: allow 'self' "
|
||||
. $GLOBALS['cfg']['CSPAllow'] . ';'
|
||||
. "options inline-script eval-script;"
|
||||
. "img-src 'self' data: "
|
||||
. $GLOBALS['cfg']['CSPAllow']
|
||||
. ($https ? "" : $mapTilesUrls)
|
||||
. ";"
|
||||
);
|
||||
} else {
|
||||
header(
|
||||
"X-WebKit-CSP: default-src 'self' "
|
||||
. $GLOBALS['cfg']['CSPAllow'] . ';'
|
||||
. "script-src 'self' "
|
||||
. $GLOBALS['cfg']['CSPAllow']
|
||||
. " 'unsafe-inline' 'unsafe-eval';"
|
||||
. "style-src 'self' 'unsafe-inline';"
|
||||
. "style-src 'self' 'unsafe-inline' "
|
||||
. ';'
|
||||
. "referrer no-referrer;"
|
||||
. "img-src 'self' data: "
|
||||
. $GLOBALS['cfg']['CSPAllow']
|
||||
. ($https ? "" : $mapTilesUrls)
|
||||
. ";"
|
||||
);
|
||||
|
||||
header(
|
||||
"X-Content-Security-Policy: default-src 'self' "
|
||||
. $GLOBALS['cfg']['CSPAllow'] . ';'
|
||||
. "options inline-script eval-script;"
|
||||
. "referrer no-referrer;"
|
||||
. "img-src 'self' data: "
|
||||
. $GLOBALS['cfg']['CSPAllow']
|
||||
. ($https ? "" : $mapTilesUrls)
|
||||
. ";"
|
||||
);
|
||||
}
|
||||
}
|
||||
PMA_noCacheHeader();
|
||||
if (! defined('IS_TRANSFORMATION_WRAPPER') && ! defined('TESTSUITE')) {
|
||||
@ -529,6 +548,7 @@ class PMA_Header
|
||||
private function _getMetaTags()
|
||||
{
|
||||
$retval = '<meta charset="utf-8" />';
|
||||
$retval .= '<meta name="referrer" content="no-referrer" />';
|
||||
$retval .= '<meta name="robots" content="noindex,nofollow" />';
|
||||
$retval .= '<meta http-equiv="X-UA-Compatible" content="IE=Edge">';
|
||||
if (! $GLOBALS['cfg']['AllowThirdPartyFraming']) {
|
||||
|
||||
@ -9,6 +9,8 @@ if (! defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
require_once './libraries/Util.class.php';
|
||||
|
||||
/**
|
||||
* Output buffering wrapper class
|
||||
*
|
||||
@ -94,7 +96,7 @@ class PMA_OutputBuffering
|
||||
if (! defined('TESTSUITE')) {
|
||||
header('X-ob_mode: ' . $this->_mode);
|
||||
}
|
||||
register_shutdown_function('PMA_OutputBuffering::stop');
|
||||
register_shutdown_function(array('PMA_OutputBuffering', 'stop'));
|
||||
$this->_on = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ class PMA_RecentTable
|
||||
// Read from phpMyAdmin database, if recent tables is not in session
|
||||
$sql_query
|
||||
= " SELECT `tables` FROM " . $this->_pmaTable .
|
||||
" WHERE `username` = '" . $GLOBALS['cfg']['Server']['user'] . "'";
|
||||
" WHERE `username` = '" . PMA_Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "'";
|
||||
|
||||
$return = array();
|
||||
$result = PMA_queryAsControlUser($sql_query, false);
|
||||
|
||||
@ -66,6 +66,13 @@ class PMA_Response
|
||||
* @var bool
|
||||
*/
|
||||
private $_isAjax;
|
||||
/**
|
||||
* Whether response object is disabled
|
||||
*
|
||||
* @access private
|
||||
* @var bool
|
||||
*/
|
||||
private $_isDisabled;
|
||||
/**
|
||||
* Whether we are servicing an ajax request for a page
|
||||
* that was fired using the generic page handler in JS.
|
||||
@ -109,6 +116,7 @@ class PMA_Response
|
||||
$this->_isSuccess = true;
|
||||
$this->_isAjax = false;
|
||||
$this->_isAjaxPage = false;
|
||||
$this->_isDisabled = false;
|
||||
if (isset($_REQUEST['ajax_request']) && $_REQUEST['ajax_request'] == true) {
|
||||
$this->_isAjax = true;
|
||||
}
|
||||
@ -181,6 +189,7 @@ class PMA_Response
|
||||
{
|
||||
$this->_header->disable();
|
||||
$this->_footer->disable();
|
||||
$this->_isDisabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -280,6 +289,12 @@ class PMA_Response
|
||||
*/
|
||||
private function _ajaxResponse()
|
||||
{
|
||||
/* Avoid wrapping in case we're disabled */
|
||||
if ($this->_isDisabled) {
|
||||
echo $this->_getDisplay();
|
||||
return;
|
||||
}
|
||||
|
||||
if (! isset($this->_JSON['message'])) {
|
||||
$this->_JSON['message'] = $this->_getDisplay();
|
||||
} else if ($this->_JSON['message'] instanceof PMA_Message) {
|
||||
|
||||
@ -50,6 +50,7 @@ class PMA_Scripts
|
||||
*/
|
||||
private function _includeFiles($files)
|
||||
{
|
||||
$first_dynamic_scripts = "";
|
||||
$dynamic_scripts = "";
|
||||
$params = array();
|
||||
foreach ($files as $value) {
|
||||
@ -67,15 +68,26 @@ class PMA_Scripts
|
||||
if ($include) {
|
||||
$params[] = "scripts[]=" . $value['filename'];
|
||||
}
|
||||
} else {
|
||||
if ($value['before_statics'] === true) {
|
||||
$first_dynamic_scripts .= "<script type='text/javascript' src='js/" . $value['filename'] . "'></script>";
|
||||
} else {
|
||||
$dynamic_scripts .= "<script type='text/javascript' src='js/" . $value['filename'] . "'></script>";
|
||||
}
|
||||
}
|
||||
$static_scripts = sprintf(
|
||||
"<script type='text/javascript' src='js/get_scripts.js.php?%s'></script>",
|
||||
implode("&", $params)
|
||||
}
|
||||
$static_scripts = '';
|
||||
// Using chunks of 10 files to avoid too long URLs
|
||||
$script_chunks = array_chunk($params, 10);
|
||||
foreach ($script_chunks as $script_chunk) {
|
||||
$url = 'js/get_scripts.js.php?' . implode('&', $script_chunk);
|
||||
|
||||
$static_scripts .= sprintf(
|
||||
'<script type="text/javascript" src="%s"></script>',
|
||||
htmlspecialchars($url)
|
||||
);
|
||||
return $static_scripts . $dynamic_scripts;
|
||||
}
|
||||
return $first_dynamic_scripts . $static_scripts . $dynamic_scripts;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,10 +109,12 @@ class PMA_Scripts
|
||||
* @param string $filename The name of the file to include
|
||||
* @param bool $conditional_ie Whether to wrap the script tag in
|
||||
* conditional comments for IE
|
||||
* @param bool $before_statics Whether this dynamic script should be
|
||||
* include before the static ones
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addFile($filename, $conditional_ie = false)
|
||||
public function addFile($filename, $conditional_ie = false, $before_statics = false)
|
||||
{
|
||||
$hash = md5($filename);
|
||||
if (empty($this->_files[$hash])) {
|
||||
@ -108,7 +122,8 @@ class PMA_Scripts
|
||||
$this->_files[$hash] = array(
|
||||
'has_onload' => $has_onload,
|
||||
'filename' => $filename,
|
||||
'conditional_ie' => $conditional_ie
|
||||
'conditional_ie' => $conditional_ie,
|
||||
'before_statics' => $before_statics
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1411,7 +1411,7 @@ class PMA_Table
|
||||
|
||||
// Read from phpMyAdmin database
|
||||
$sql_query = " SELECT `prefs` FROM " . $pma_table
|
||||
. " WHERE `username` = '" . $GLOBALS['cfg']['Server']['user'] . "'"
|
||||
. " WHERE `username` = '" . PMA_Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "'"
|
||||
. " AND `db_name` = '" . PMA_Util::sqlAddSlashes($this->db_name) . "'"
|
||||
. " AND `table_name` = '" . PMA_Util::sqlAddSlashes($this->name) . "'";
|
||||
|
||||
@ -1435,7 +1435,7 @@ class PMA_Table
|
||||
|
||||
$username = $GLOBALS['cfg']['Server']['user'];
|
||||
$sql_query = " REPLACE INTO " . $pma_table
|
||||
. " VALUES ('" . $username . "', '" . PMA_Util::sqlAddSlashes($this->db_name)
|
||||
. " VALUES ('" . PMA_Util::sqlAddSlashes($username) . "', '" . PMA_Util::sqlAddSlashes($this->db_name)
|
||||
. "', '" . PMA_Util::sqlAddSlashes($this->name) . "', '"
|
||||
. PMA_Util::sqlAddSlashes(json_encode($this->uiprefs)) . "', NULL)";
|
||||
|
||||
|
||||
@ -307,6 +307,7 @@ EOT;
|
||||
private function _getEnumSetInputBox($column_index, $criteriaValues,
|
||||
$column_type, $column_id, $in_zoom_search_edit = false
|
||||
) {
|
||||
$column_type = htmlspecialchars($column_type);
|
||||
$html_output = '';
|
||||
$value = explode(
|
||||
', ',
|
||||
@ -932,7 +933,9 @@ EOT;
|
||||
$html_output .= '<th>'
|
||||
. htmlspecialchars($this->_columnNames[$column_index]) . '</th>';
|
||||
$properties = $this->getColumnProperties($column_index, $column_index);
|
||||
$html_output .= '<td>' . $properties['type'] . '</td>';
|
||||
$html_output .= '<td>'
|
||||
. htmlspecialchars($properties['type'])
|
||||
. '</td>';
|
||||
$html_output .= '<td>' . $properties['collation'] . '</td>';
|
||||
$html_output .= '<td>' . $properties['func'] . '</td>';
|
||||
$html_output .= '<td>' . $properties['value'] . '</td>';
|
||||
@ -941,11 +944,13 @@ EOT;
|
||||
$html_output .= '<tr><td>';
|
||||
$html_output .= '<input type="hidden"'
|
||||
. ' name="criteriaColumnNames[' . $column_index . ']"'
|
||||
. ' value="' . htmlspecialchars($this->_columnNames[$column_index])
|
||||
. ' value="'
|
||||
. htmlspecialchars($this->_columnNames[$column_index])
|
||||
. '" />';
|
||||
$html_output .= '<input type="hidden"'
|
||||
. ' name="criteriaColumnTypes[' . $column_index . ']"'
|
||||
. ' value="' . $this->_columnTypes[$column_index] . '" />';
|
||||
. ' value="'
|
||||
. htmlspecialchars($this->_columnTypes[$column_index]) . '" />';
|
||||
$html_output .= '<input type="hidden"'
|
||||
. ' name="criteriaColumnCollations[' . $column_index . ']"'
|
||||
. ' value="' . $this->_columnCollations[$column_index] . '" />';
|
||||
@ -1012,21 +1017,21 @@ EOT;
|
||||
$value[$i] = $properties['value'];
|
||||
}
|
||||
//Column type
|
||||
$html_output .= '<td>' . (isset($type[$i]) ? $type[$i] : '') . '</td>';
|
||||
$html_output .= '<td>' . (isset($type[$i]) ? htmlspecialchars($type[$i]) : '') . '</td>';
|
||||
//Column Collation
|
||||
$html_output .= '<td>' . (isset($collation[$i]) ? $collation[$i] : '')
|
||||
. '</td>';
|
||||
//Select options for column operators
|
||||
$html_output .= '<td>' . (isset($func[$i]) ? $func[$i] : '') . '</td>';
|
||||
//Inputbox for search criteria value
|
||||
$html_output .= '<td>' . (isset($value[$i]) ? $value[$i] : '') . '</td>';
|
||||
$html_output .= '<td>' . (isset($value[$i]) ? htmlspecialchars($value[$i]) : '') . '</td>';
|
||||
$html_output .= '</tr>';
|
||||
//Displays hidden fields
|
||||
$html_output .= '<tr><td>';
|
||||
$html_output .= '<input type="hidden" name="criteriaColumnTypes[' . $i . ']"'
|
||||
. ' id="types_' . $i . '" ';
|
||||
if (isset($_POST['criteriaColumnTypes'][$i])) {
|
||||
$html_output .= 'value="' . $_POST['criteriaColumnTypes'][$i] . '" ';
|
||||
$html_output .= 'value="' . htmlspecialchars($_POST['criteriaColumnTypes'][$i]) . '" ';
|
||||
}
|
||||
$html_output .= '/>';
|
||||
$html_output .= '<input type="hidden" name="criteriaColumnCollations['
|
||||
@ -1175,7 +1180,7 @@ EOT;
|
||||
$html_output .= '<center><a href="#" onclick="displayHelp();">'
|
||||
. __('How to use') . '</a></center>';
|
||||
$html_output .= '<div id="querydata" style="display:none">'
|
||||
. json_encode($data) . '</div>';
|
||||
. htmlspecialchars(json_encode($data)) . '</div>';
|
||||
$html_output .= '<div id="querychart"></div>';
|
||||
$html_output .= '<button class="button-reset">'
|
||||
. __('Reset zoom') . '</button>';
|
||||
|
||||
@ -490,9 +490,6 @@ class PMA_Theme
|
||||
if (!is_null($fs)) {
|
||||
return $fs;
|
||||
}
|
||||
if (isset($_COOKIE['pma_fontsize'])) {
|
||||
return $_COOKIE['pma_fontsize'];
|
||||
}
|
||||
return '82%';
|
||||
}
|
||||
|
||||
|
||||
@ -230,8 +230,9 @@ class PMA_Tracker
|
||||
static public function getLogComment()
|
||||
{
|
||||
$date = date('Y-m-d H:i:s');
|
||||
$user = preg_replace('/\s+/', ' ', $GLOBALS['cfg']['Server']['user']);
|
||||
|
||||
return "# log " . $date . " " . $GLOBALS['cfg']['Server']['user'] . "\n";
|
||||
return "# log " . $date . " " . $user . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -552,7 +552,7 @@ class PMA_Util
|
||||
/* Check if we have built local documentation */
|
||||
if (defined('TESTSUITE')) {
|
||||
/* Provide consistent URL for testsuite */
|
||||
return PMA_linkURL('http://docs.phpmyadmin.net/en/latest/' . $url);
|
||||
return PMA_linkURL('https://docs.phpmyadmin.net/en/latest/' . $url);
|
||||
} else if (file_exists('doc/html/index.html')) {
|
||||
if (defined('PMA_SETUP')) {
|
||||
return '../doc/html/' . $url;
|
||||
@ -561,7 +561,7 @@ class PMA_Util
|
||||
}
|
||||
} else {
|
||||
/* TODO: Should link to correct branch for released versions */
|
||||
return PMA_linkURL('http://docs.phpmyadmin.net/en/latest/' . $url);
|
||||
return PMA_linkURL('https://docs.phpmyadmin.net/en/latest/' . $url);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2659,7 +2659,7 @@ class PMA_Util
|
||||
$dir .= '/';
|
||||
}
|
||||
|
||||
return str_replace('%u', $GLOBALS['cfg']['Server']['user'], $dir);
|
||||
return str_replace('%u', PMA_securePath($GLOBALS['cfg']['Server']['user']), $dir);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3150,8 +3150,11 @@ class PMA_Util
|
||||
// for the case ENUM('–','“')
|
||||
$displayed_type = htmlspecialchars($printtype);
|
||||
if (strlen($printtype) > $GLOBALS['cfg']['LimitChars']) {
|
||||
$displayed_type = '<abbr title="' . $printtype . '">';
|
||||
$displayed_type .= substr($printtype, 0, $GLOBALS['cfg']['LimitChars']);
|
||||
$displayed_type = '<abbr title="'
|
||||
. htmlspecialchars($printtype) . '">';
|
||||
$displayed_type .= htmlspecialchars(
|
||||
substr($printtype, 0, $GLOBALS['cfg']['LimitChars'])
|
||||
);
|
||||
$displayed_type .= '</abbr>';
|
||||
}
|
||||
|
||||
@ -4148,5 +4151,94 @@ class PMA_Util
|
||||
. PMA_Util::localisedDate(strtotime($table['Check_time']));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version and date of the latest phpMyAdmin version compatible
|
||||
* with avilable PHP and MySQL versions
|
||||
*
|
||||
* @param array $releases array of information related to each version
|
||||
*
|
||||
* @return array containing the version and date of latest compatibel version
|
||||
*/
|
||||
public static function getLatestCompatibleVersion($releases)
|
||||
{
|
||||
foreach ($releases as $release) {
|
||||
$phpVersions = $release->php_versions;
|
||||
$phpConditions = explode(",", $phpVersions);
|
||||
foreach ($phpConditions as $phpCondition) {
|
||||
if (! self::evaluateVersionCondition("PHP", $phpCondition)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
// We evalute MySQL version constraint if there are only
|
||||
// one server configured.
|
||||
if (count($GLOBALS['cfg']['Servers']) == 1) {
|
||||
$mysqlVersions = $release->mysql_versions;
|
||||
$mysqlConditions = explode(",", $mysqlVersions);
|
||||
foreach ($mysqlConditions as $mysqlCondition) {
|
||||
if (! self::evaluateVersionCondition('MySQL', $mysqlCondition)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'version' => $release->version,
|
||||
'date' => $release->date,
|
||||
);
|
||||
}
|
||||
|
||||
// no compatible version
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether PHP or MySQL version meets supplied version condition
|
||||
*
|
||||
* @param string $type PHP or MySQL
|
||||
* @param string $condition version condition
|
||||
*
|
||||
* @return boolean whether the condition is met
|
||||
*/
|
||||
public static function evaluateVersionCondition($type, $condition)
|
||||
{
|
||||
$operator = null;
|
||||
$operators = array("<=", ">=", "!=", "<>", "<", ">", "="); // preserve order
|
||||
foreach ($operators as $oneOperator) {
|
||||
if (strpos($condition, $oneOperator) === 0) {
|
||||
$operator = $oneOperator;
|
||||
$version = substr($condition, strlen($oneOperator));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$myVersion = null;
|
||||
if ($type == 'PHP') {
|
||||
$myVersion = PHP_VERSION;
|
||||
} elseif ($type == 'MySQL') {
|
||||
$myVersion = PMA_Util::cacheGet('PMA_MYSQL_STR_VERSION', true);
|
||||
}
|
||||
|
||||
if ($myVersion != null && $operator != null) {
|
||||
return version_compare($myVersion, $version, $operator);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts given (request) paramter to string
|
||||
*
|
||||
* @param mixed $value Value to convert
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function requestString($value)
|
||||
{
|
||||
while (is_array($value) || is_object($value)) {
|
||||
$value = reset($value);
|
||||
}
|
||||
return trim((string)$value);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@ -166,10 +166,10 @@ function PMA_buildHtmlForDb(
|
||||
. '" href="server_privileges.php?' . $url_query
|
||||
. '&checkprivs=' . urlencode($current['SCHEMA_NAME'])
|
||||
. '" title="'
|
||||
. sprintf(
|
||||
__('Check privileges for database "%s".'),
|
||||
htmlspecialchars($current['SCHEMA_NAME'])
|
||||
)
|
||||
. htmlspecialchars(sprintf(
|
||||
__('Check privileges for database "%s".'),
|
||||
$current['SCHEMA_NAME']
|
||||
))
|
||||
. '">'
|
||||
. ' '
|
||||
. PMA_Util::getIcon('s_rights.png', __('Check Privileges'))
|
||||
|
||||
@ -143,7 +143,7 @@ require './libraries/Table.class.php';
|
||||
*/
|
||||
require './libraries/Types.class.php';
|
||||
|
||||
if (! defined('PMA_MINIMUM_COMMON')) {
|
||||
if (! defined('PMA_MINIMUM_COMMON') || defined('PMA_SETUP')) {
|
||||
/**
|
||||
* common functions
|
||||
*/
|
||||
@ -235,7 +235,7 @@ unset($key, $value, $variables_whitelist);
|
||||
* so we now check if a subform is submitted
|
||||
*/
|
||||
$__redirect = null;
|
||||
if (isset($_POST['usesubform'])) {
|
||||
if (isset($_POST['usesubform']) && ! defined('PMA_MINIMUM_COMMON')) {
|
||||
// if a subform is present and should be used
|
||||
// the rest of the form is deprecated
|
||||
$subform_id = key($_POST['usesubform']);
|
||||
@ -346,6 +346,7 @@ if (isset($_COOKIE)
|
||||
if ($GLOBALS['PMA_Config']->get('ForceSSL')
|
||||
&& ! $GLOBALS['PMA_Config']->get('is_https')
|
||||
) {
|
||||
require './libraries/select_lang.lib.php';
|
||||
// grab SSL URL
|
||||
$url = $GLOBALS['PMA_Config']->getSSLUri();
|
||||
// Actually redirect
|
||||
@ -400,7 +401,6 @@ $goto_whitelist = array(
|
||||
'index.php',
|
||||
'pdf_pages.php',
|
||||
'pdf_schema.php',
|
||||
//'phpinfo.php',
|
||||
'querywindow.php',
|
||||
'server_binlog.php',
|
||||
'server_collations.php',
|
||||
@ -482,7 +482,7 @@ if (PMA_checkPageValidity($_REQUEST['back'], $goto_whitelist)) {
|
||||
*/
|
||||
$token_mismatch = true;
|
||||
if (PMA_isValid($_REQUEST['token'])) {
|
||||
$token_mismatch = ($_SESSION[' PMA_token '] != $_REQUEST['token']);
|
||||
$token_mismatch = ! hash_equals($_SESSION[' PMA_token '], $_REQUEST['token']);
|
||||
}
|
||||
|
||||
if ($token_mismatch) {
|
||||
@ -503,7 +503,9 @@ if ($token_mismatch) {
|
||||
/* Needed to send the correct reply */
|
||||
'ajax_request',
|
||||
/* Permit to log out even if there is a token mismatch */
|
||||
'old_usr'
|
||||
'old_usr',
|
||||
/* url.php */
|
||||
'url',
|
||||
);
|
||||
/**
|
||||
* Allow changing themes in test/theme.php
|
||||
@ -866,6 +868,9 @@ if (! defined('PMA_MINIMUM_COMMON')) {
|
||||
. ' ' . $cfg['Server']['auth_type']
|
||||
);
|
||||
}
|
||||
if (isset($_REQUEST['pma_password']) && strlen($_REQUEST['pma_password']) > 256) {
|
||||
$_REQUEST['pma_password'] = substr($_REQUEST['pma_password'], 0, 256);
|
||||
}
|
||||
include_once './libraries/plugins/auth/' . $auth_class . '.class.php';
|
||||
// todo: add plugin manager
|
||||
$plugin_manager = null;
|
||||
@ -974,6 +979,8 @@ if (! defined('PMA_MINIMUM_COMMON')) {
|
||||
$controllink = $userlink;
|
||||
}
|
||||
|
||||
$auth_plugin->storeUserCredentials();
|
||||
|
||||
/* Log success */
|
||||
PMA_log_user($cfg['Server']['user']);
|
||||
|
||||
|
||||
@ -207,14 +207,6 @@ $cfg['Servers'][$i]['auth_type'] = 'cookie';
|
||||
*/
|
||||
$cfg['Servers'][$i]['auth_http_realm'] = '';
|
||||
|
||||
/**
|
||||
* File containing Swekey ids and login names (see /contrib);
|
||||
* leave empty to deactivate Swekey hardware authentication
|
||||
*
|
||||
* @global string $cfg['Servers'][$i]['auth_swekey_config']
|
||||
*/
|
||||
$cfg['Servers'][$i]['auth_swekey_config'] = '';
|
||||
|
||||
/**
|
||||
* MySQL user
|
||||
*
|
||||
@ -912,13 +904,6 @@ $cfg['NavigationTreeDefaultTabTable'] = 'tbl_structure.php';
|
||||
*/
|
||||
$cfg['ShowStats'] = true;
|
||||
|
||||
/**
|
||||
* show PHP info link
|
||||
*
|
||||
* @global boolean $cfg['ShowPhpInfo']
|
||||
*/
|
||||
$cfg['ShowPhpInfo'] = false;
|
||||
|
||||
/**
|
||||
* show MySQL server and web server information
|
||||
*
|
||||
|
||||
@ -486,21 +486,6 @@ class ConfigFile
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns config file path, relative to phpMyAdmin's root path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFilePath()
|
||||
{
|
||||
// Load paths
|
||||
if (!defined('SETUP_CONFIG_FILE')) {
|
||||
include_once './libraries/vendor_config.php';
|
||||
}
|
||||
|
||||
return SETUP_CONFIG_FILE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns configuration array (full, multidimensional format)
|
||||
*
|
||||
|
||||
@ -562,11 +562,13 @@ class FormDisplay
|
||||
// cast variables to correct type
|
||||
switch ($type) {
|
||||
case 'double':
|
||||
$_POST[$key] = PMA_Util::requestString($_POST[$key]);
|
||||
settype($_POST[$key], 'float');
|
||||
break;
|
||||
case 'boolean':
|
||||
case 'integer':
|
||||
if ($_POST[$key] !== '') {
|
||||
$_POST[$key] = PMA_Util::requestString($_POST[$key]);
|
||||
settype($_POST[$key], $type);
|
||||
}
|
||||
break;
|
||||
@ -583,7 +585,7 @@ class FormDisplay
|
||||
break;
|
||||
case 'string':
|
||||
case 'short_string':
|
||||
$_POST[$key] = trim($_POST[$key]);
|
||||
$_POST[$key] = PMA_Util::requestString($_POST[$key]);
|
||||
break;
|
||||
case 'array':
|
||||
// eliminate empty values and ensure we have an array
|
||||
@ -592,7 +594,7 @@ class FormDisplay
|
||||
: explode("\n", $_POST[$key]);
|
||||
$_POST[$key] = array();
|
||||
foreach ($post_values as $v) {
|
||||
$v = trim($v);
|
||||
$v = PMA_Util::requestString($v);
|
||||
if ($v !== '') {
|
||||
$_POST[$key][] = $v;
|
||||
}
|
||||
@ -708,7 +710,7 @@ class FormDisplay
|
||||
if ($test == 'Export') {
|
||||
$opt_name = substr($opt_name, 7);
|
||||
}
|
||||
return PMA_linkURL('http://wiki.phpmyadmin.net/pma/Config#' . $opt_name);
|
||||
return PMA_linkURL('https://wiki.phpmyadmin.net/pma/Config#' . $opt_name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
*/
|
||||
|
||||
if (!function_exists('__')) {
|
||||
PMA_fatalError('Bad invocation!');
|
||||
exit();
|
||||
}
|
||||
|
||||
$strConfigAllowArbitraryServer_desc = __('If enabled user can enter any MySQL server in login form for cookie auth');
|
||||
@ -373,11 +373,9 @@ $strConfigServers_AllowNoPassword_name = __('Allow logins without a password');
|
||||
$strConfigServers_AllowRoot_name = __('Allow root login');
|
||||
$strConfigServers_auth_http_realm_desc = __('HTTP Basic Auth Realm name to display when doing HTTP Auth');
|
||||
$strConfigServers_auth_http_realm_name = __('HTTP Realm');
|
||||
$strConfigServers_auth_swekey_config_desc = __('The path for the config file for [a@http://swekey.com]SweKey hardware authentication[/a] (not located in your document root; suggested: /etc/swekey.conf)');
|
||||
$strConfigServers_auth_swekey_config_name = __('SweKey config file');
|
||||
$strConfigServers_auth_type_desc = __('Authentication method to use');
|
||||
$strConfigServers_auth_type_name = __('Authentication type');
|
||||
$strConfigServers_bookmarktable_desc = __('Leave blank for no [a@http://wiki.phpmyadmin.net/pma/bookmark]bookmark[/a] support, suggested: [kbd]pma__bookmark[/kbd]');
|
||||
$strConfigServers_bookmarktable_desc = __('Leave blank for no [a@https://wiki.phpmyadmin.net/pma/bookmark]bookmark[/a] support, suggested: [kbd]pma__bookmark[/kbd]');
|
||||
$strConfigServers_bookmarktable_name = __('Bookmark table');
|
||||
$strConfigServers_column_info_desc = __('Leave blank for no column comments/mime types, suggested: [kbd]pma__column_info[/kbd]');
|
||||
$strConfigServers_column_info_name = __('Column information table');
|
||||
@ -386,7 +384,7 @@ $strConfigServers_compress_name = __('Compress connection');
|
||||
$strConfigServers_connect_type_desc = __('How to connect to server, keep [kbd]tcp[/kbd] if unsure');
|
||||
$strConfigServers_connect_type_name = __('Connection type');
|
||||
$strConfigServers_controlpass_name = __('Control user password');
|
||||
$strConfigServers_controluser_desc = __('A special MySQL user configured with limited permissions, more information available on [a@http://wiki.phpmyadmin.net/pma/controluser]wiki[/a]');
|
||||
$strConfigServers_controluser_desc = __('A special MySQL user configured with limited permissions, more information available on [a@https://wiki.phpmyadmin.net/pma/controluser]wiki[/a]');
|
||||
$strConfigServers_controluser_name = __('Control user');
|
||||
$strConfigServers_controlhost_desc = __('An alternate host to hold the configuration storage; leave blank to use the already defined host');
|
||||
$strConfigServers_controlhost_name = __('Control host');
|
||||
@ -413,17 +411,17 @@ $strConfigServers_password_desc = __('Leave empty if not using config auth');
|
||||
$strConfigServers_password_name = __('Password for config auth');
|
||||
$strConfigServers_pdf_pages_desc = __('Leave blank for no PDF schema support, suggested: [kbd]pma__pdf_pages[/kbd]');
|
||||
$strConfigServers_pdf_pages_name = __('PDF schema: pages table');
|
||||
$strConfigServers_pmadb_desc = __('Database used for relations, bookmarks, and PDF features. See [a@http://wiki.phpmyadmin.net/pma/pmadb]pmadb[/a] for complete information. Leave blank for no support. Suggested: [kbd]phpmyadmin[/kbd]');
|
||||
$strConfigServers_pmadb_desc = __('Database used for relations, bookmarks, and PDF features. See [a@https://wiki.phpmyadmin.net/pma/pmadb]pmadb[/a] for complete information. Leave blank for no support. Suggested: [kbd]phpmyadmin[/kbd]');
|
||||
$strConfigServers_pmadb_name = __('Database name');
|
||||
$strConfigServers_port_desc = __('Port on which MySQL server is listening, leave empty for default');
|
||||
$strConfigServers_port_name = __('Server port');
|
||||
$strConfigServers_recent_desc = __('Leave blank for no "persistent" recently used tables across sessions, suggested: [kbd]pma__recent[/kbd]');
|
||||
$strConfigServers_recent_name = __('Recently used table');
|
||||
$strConfigServers_relation_desc = __('Leave blank for no [a@http://wiki.phpmyadmin.net/pma/relation]relation-links[/a] support, suggested: [kbd]pma__relation[/kbd]');
|
||||
$strConfigServers_relation_desc = __('Leave blank for no [a@https://wiki.phpmyadmin.net/pma/relation]relation-links[/a] support, suggested: [kbd]pma__relation[/kbd]');
|
||||
$strConfigServers_relation_name = __('Relation table');
|
||||
$strConfigServers_ShowDatabasesCommand_desc = __('SQL command to fetch available databases');
|
||||
$strConfigServers_ShowDatabasesCommand_name = __('SHOW DATABASES command');
|
||||
$strConfigServers_SignonSession_desc = __('See [a@http://wiki.phpmyadmin.net/pma/auth_types#signon]authentication types[/a] for an example');
|
||||
$strConfigServers_SignonSession_desc = __('See [a@https://wiki.phpmyadmin.net/pma/auth_types#signon]authentication types[/a] for an example');
|
||||
$strConfigServers_SignonSession_name = __('Signon session name');
|
||||
$strConfigServers_SignonURL_name = __('Signon URL');
|
||||
$strConfigServers_socket_desc = __('Socket on which MySQL server is listening, leave empty for default');
|
||||
@ -473,8 +471,6 @@ $strConfigShowFunctionFields_desc = __('Display the function fields in edit/inse
|
||||
$strConfigShowFunctionFields_name = __('Show function fields');
|
||||
$strConfigShowHint_desc = __('Whether to show hint or not');
|
||||
$strConfigShowHint_name = __('Show hint');
|
||||
$strConfigShowPhpInfo_desc = __('Shows link to [a@http://php.net/manual/function.phpinfo.php]phpinfo()[/a] output');
|
||||
$strConfigShowPhpInfo_name = __('Show phpinfo() link');
|
||||
$strConfigShowServerInfo_name = __('Show detailed MySQL server information');
|
||||
$strConfigShowSQL_desc = __('Defines whether SQL queries generated by phpMyAdmin should be displayed');
|
||||
$strConfigShowSQL_name = __('Show SQL queries');
|
||||
|
||||
@ -42,9 +42,6 @@ $forms['Servers']['Server_auth'] = array('Servers' => array(1 => array(
|
||||
'user',
|
||||
'password',
|
||||
':group:end',
|
||||
':group:' . __('Cookie authentication'),
|
||||
'auth_swekey_config' => './swekey.conf',
|
||||
':group:end',
|
||||
':group:' . __('HTTP authentication'),
|
||||
'auth_http_realm',
|
||||
':group:end',
|
||||
@ -183,7 +180,6 @@ $forms['Main_panel']['Startup'] = array(
|
||||
'ShowCreateDb',
|
||||
'ShowStats',
|
||||
'ShowServerInfo',
|
||||
'ShowPhpInfo',
|
||||
'ShowChgPassword');
|
||||
$forms['Main_panel']['DbStructure'] = array(
|
||||
'ShowDbStructureCreation',
|
||||
|
||||
@ -15,6 +15,8 @@
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
require_once './libraries/Util.class.php';
|
||||
|
||||
/**
|
||||
* Returns validator list
|
||||
*
|
||||
@ -275,6 +277,11 @@ function validate_server($path, $values)
|
||||
'Servers/1/SignonURL' => ''
|
||||
);
|
||||
$error = false;
|
||||
if (empty($values['Servers/1/auth_type'])) {
|
||||
$values['Servers/1/auth_type'] = '';
|
||||
$result['Servers/1/auth_type'] = __('Invalid authentication type!');
|
||||
$error = true;
|
||||
}
|
||||
if ($values['Servers/1/auth_type'] == 'config'
|
||||
&& empty($values['Servers/1/user'])
|
||||
) {
|
||||
@ -300,15 +307,15 @@ function validate_server($path, $values)
|
||||
}
|
||||
|
||||
if (!$error && $values['Servers/1/auth_type'] == 'config') {
|
||||
$password = $values['Servers/1/nopassword'] ? null
|
||||
: $values['Servers/1/password'];
|
||||
$password = !empty($values['Servers/1/nopassword']) && $values['Servers/1/nopassword'] ? null
|
||||
: (empty($values['Servers/1/password']) ? '' : $values['Servers/1/password']);
|
||||
$test = test_db_connection(
|
||||
$values['Servers/1/extension'],
|
||||
$values['Servers/1/connect_type'],
|
||||
$values['Servers/1/host'],
|
||||
$values['Servers/1/port'],
|
||||
$values['Servers/1/socket'],
|
||||
$values['Servers/1/user'],
|
||||
empty($values['Servers/1/extension']) ? '' : $values['Servers/1/extension'],
|
||||
empty($values['Servers/1/connect_type']) ? '' : $values['Servers/1/connect_type'],
|
||||
empty($values['Servers/1/host']) ? '' : PMA_sanitizeMySQLHost($values['Servers/1/host']),
|
||||
empty($values['Servers/1/port']) ? '' : $values['Servers/1/port'],
|
||||
empty($values['Servers/1/socket']) ? '' : $values['Servers/1/socket'],
|
||||
empty($values['Servers/1/user']) ? '' : $values['Servers/1/user'],
|
||||
$password,
|
||||
'Server'
|
||||
);
|
||||
@ -336,17 +343,17 @@ function validate_pmadb($path, $values)
|
||||
);
|
||||
$error = false;
|
||||
|
||||
if ($values['Servers/1/pmadb'] == '') {
|
||||
if (empty($values['Servers/1/pmadb'])) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
if ($values['Servers/1/controluser'] == '') {
|
||||
if (empty($values['Servers/1/controluser'])) {
|
||||
$result['Servers/1/controluser']
|
||||
= __('Empty phpMyAdmin control user while using pmadb');
|
||||
$error = true;
|
||||
}
|
||||
if ($values['Servers/1/controlpass'] == '') {
|
||||
if (empty($values['Servers/1/controlpass'])) {
|
||||
$result['Servers/1/controlpass']
|
||||
= __('Empty phpMyAdmin control user password while using pmadb');
|
||||
$error = true;
|
||||
@ -354,7 +361,7 @@ function validate_pmadb($path, $values)
|
||||
if (!$error) {
|
||||
$test = test_db_connection(
|
||||
$values['Servers/1/extension'], $values['Servers/1/connect_type'],
|
||||
$values['Servers/1/host'], $values['Servers/1/port'],
|
||||
$values['Servers/1/host'], PMA_sanitizeMySQLHost($values['Servers/1/port']),
|
||||
$values['Servers/1/socket'], $values['Servers/1/controluser'],
|
||||
$values['Servers/1/controlpass'], 'Server_pmadb'
|
||||
);
|
||||
@ -378,7 +385,7 @@ function validate_regex($path, $values)
|
||||
{
|
||||
$result = array($path => '');
|
||||
|
||||
if ($values[$path] == '') {
|
||||
if (empty($values[$path])) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
@ -415,10 +422,11 @@ function validate_trusted_proxies($path, $values)
|
||||
return $result;
|
||||
}
|
||||
|
||||
if (is_array($values[$path])) {
|
||||
if (is_array($values[$path]) || is_object($values[$path])) {
|
||||
// value already processed by FormDisplay::save
|
||||
$lines = array();
|
||||
foreach ($values[$path] as $ip => $v) {
|
||||
$v = PMA_Util::requestString($v);
|
||||
$lines[] = preg_match('/^-\d+$/', $ip)
|
||||
? $v
|
||||
: $ip . ': ' . $v;
|
||||
@ -469,7 +477,7 @@ function test_number(
|
||||
$max_value,
|
||||
$error_string
|
||||
) {
|
||||
if ($values[$path] === '') {
|
||||
if (empty($values[$path])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
@ -562,7 +570,11 @@ function validate_non_negative_number($path, $values)
|
||||
*/
|
||||
function validate_by_regex($path, $values, $regex)
|
||||
{
|
||||
$result = preg_match($regex, $values[$path]);
|
||||
if (empty($values[$path])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$result = preg_match($regex, PMA_Util::requestString($values[$path]));
|
||||
return array($path => ($result ? '' : __('Incorrect value')));
|
||||
}
|
||||
|
||||
|
||||
@ -552,7 +552,7 @@ function PMA_sendHeaderLocation($uri, $use_refresh = false)
|
||||
echo '<body>' . "\n";
|
||||
echo '<script type="text/javascript">' . "\n";
|
||||
echo '//<![CDATA[' . "\n";
|
||||
echo 'document.write(\'<p><a href="' . htmlspecialchars($uri) . '">'
|
||||
echo 'document.write(\'<p><a href="' . PMA_escapeJsString(htmlspecialchars($uri)) . '">'
|
||||
. __('Go') . '</a></p>\');' . "\n";
|
||||
echo '//]]>' . "\n";
|
||||
echo '</script></body></html>' . "\n";
|
||||
@ -568,11 +568,6 @@ function PMA_sendHeaderLocation($uri, $use_refresh = false)
|
||||
} else {
|
||||
session_write_close();
|
||||
if (headers_sent()) {
|
||||
if (function_exists('debug_print_backtrace')) {
|
||||
echo '<pre>';
|
||||
debug_print_backtrace();
|
||||
echo '</pre>';
|
||||
}
|
||||
trigger_error(
|
||||
'PMA_sendHeaderLocation called when headers are already sent!',
|
||||
E_USER_ERROR
|
||||
@ -755,7 +750,7 @@ function PMA_arrayRemove($path, &$array)
|
||||
*/
|
||||
function PMA_linkURL($url)
|
||||
{
|
||||
if (!preg_match('#^https?://#', $url) || defined('PMA_SETUP')) {
|
||||
if (!preg_match('#^https?://#', $url)) {
|
||||
return $url;
|
||||
} else {
|
||||
if (!function_exists('PMA_generate_common_url')) {
|
||||
@ -763,9 +758,13 @@ function PMA_linkURL($url)
|
||||
}
|
||||
$params = array();
|
||||
$params['url'] = $url;
|
||||
if (defined('PMA_SETUP')) {
|
||||
return '../url.php' . PMA_generate_common_url($params);
|
||||
} else {
|
||||
return './url.php' . PMA_generate_common_url($params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds JS code snippets to be displayed by the PMA_Response class.
|
||||
@ -799,4 +798,217 @@ function PMA_addJSVar($key, $value, $escape = true)
|
||||
PMA_addJSCode(PMA_getJsValue($key, $value, $escape));
|
||||
}
|
||||
|
||||
/* Compatibility with PHP < 5.6 */
|
||||
if(! function_exists('hash_equals')) {
|
||||
function hash_equals($a, $b) {
|
||||
$ret = strlen($a) ^ strlen($b);
|
||||
$ret |= array_sum(unpack("C*", $a ^ $b));
|
||||
return ! $ret;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether domain of URL is whitelisted domain or not.
|
||||
* Use only for URLs of external sites.
|
||||
*
|
||||
* @param string $url URL of external site.
|
||||
*
|
||||
* @return boolean.True:if domain of $url is allowed domain, False:otherwise.
|
||||
*/
|
||||
function PMA_isAllowedDomain($url)
|
||||
{
|
||||
$arr = parse_url($url);
|
||||
// We need host to be set
|
||||
if (! isset($arr['host']) || strlen($arr['host']) == 0) {
|
||||
return false;
|
||||
}
|
||||
// We do not want these to be present
|
||||
$blocked = array('user', 'pass', 'port');
|
||||
foreach ($blocked as $part) {
|
||||
if (isset($arr[$part]) && strlen($arr[$part]) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$domain = $arr["host"];
|
||||
$domainWhiteList = array(
|
||||
/* Include current domain */
|
||||
$_SERVER['SERVER_NAME'],
|
||||
/* phpMyAdmin domains */
|
||||
'wiki.phpmyadmin.net', 'www.phpmyadmin.net', 'phpmyadmin.net',
|
||||
'docs.phpmyadmin.net',
|
||||
'demo.phpmyadmin.net',
|
||||
/* mysql.com domains */
|
||||
'dev.mysql.com','bugs.mysql.com',
|
||||
/* mariadb domains */
|
||||
'mariadb.org', 'mariadb.com',
|
||||
/* php.net domains */
|
||||
'php.net',
|
||||
/* sourceforge.net domain */
|
||||
'sourceforge.net',
|
||||
/* Github domains*/
|
||||
'github.com','www.github.com',
|
||||
/* Percona domains */
|
||||
'www.percona.com',
|
||||
/* Following are doubtful ones. */
|
||||
'www.primebase.com','pbxt.blogspot.com',
|
||||
'mysqldatabaseadministration.blogspot.com',
|
||||
/* CVE */
|
||||
'cve.mitre.org',
|
||||
);
|
||||
if (in_array($domain, $domainWhiteList)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/* Compatibility with PHP < 5.1 or PHP without hash extension */
|
||||
if (! function_exists('hash_hmac')) {
|
||||
function hash_hmac($algo, $data, $key, $raw_output = false)
|
||||
{
|
||||
$algo = strtolower($algo);
|
||||
$pack = 'H'.strlen($algo('test'));
|
||||
$size = 64;
|
||||
$opad = str_repeat(chr(0x5C), $size);
|
||||
$ipad = str_repeat(chr(0x36), $size);
|
||||
|
||||
if (strlen($key) > $size) {
|
||||
$key = str_pad(pack($pack, $algo($key)), $size, chr(0x00));
|
||||
} else {
|
||||
$key = str_pad($key, $size, chr(0x00));
|
||||
}
|
||||
|
||||
for ($i = 0; $i < strlen($key) - 1; $i++) {
|
||||
$opad[$i] = $opad[$i] ^ $key[$i];
|
||||
$ipad[$i] = $ipad[$i] ^ $key[$i];
|
||||
}
|
||||
|
||||
$output = $algo($opad.pack($pack, $algo($ipad.$data)));
|
||||
|
||||
return ($raw_output) ? pack($pack, $output) : $output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes MySQL hostname
|
||||
*
|
||||
* * strips p: prefix(es)
|
||||
*
|
||||
* @param string $name User given hostname
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function PMA_sanitizeMySQLHost($name)
|
||||
{
|
||||
while (strtolower(substr($name, 0, 2)) == 'p:') {
|
||||
$name = substr($name, 2);
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes MySQL username
|
||||
*
|
||||
* * strips part behind null byte
|
||||
*
|
||||
* @param string $name User given username
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function PMA_sanitizeMySQLUser($name)
|
||||
{
|
||||
$position = strpos($name, chr(0));
|
||||
if ($position !== false) {
|
||||
return substr($name, 0, $position);
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe unserializer wrapper
|
||||
*
|
||||
* It does not unserialize data containing objects
|
||||
*
|
||||
* @param string $data Data to unserialize
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function PMA_safeUnserialize($data)
|
||||
{
|
||||
if (! is_string($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* validate serialized data */
|
||||
$length = strlen($data);
|
||||
$depth = 0;
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$value = $data[$i];
|
||||
|
||||
switch ($value)
|
||||
{
|
||||
case '}':
|
||||
/* end of array */
|
||||
if ($depth <= 0) {
|
||||
return null;
|
||||
}
|
||||
$depth--;
|
||||
break;
|
||||
case 's':
|
||||
/* string */
|
||||
// parse sting length
|
||||
$strlen = intval(substr($data, $i + 2));
|
||||
// string start
|
||||
$i = strpos($data, ':', $i + 2);
|
||||
if ($i === false) {
|
||||
return null;
|
||||
}
|
||||
// skip string, quotes and ;
|
||||
$i += 2 + $strlen + 1;
|
||||
if ($data[$i] != ';') {
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
case 'i':
|
||||
case 'd':
|
||||
/* bool, integer or double */
|
||||
// skip value to sepearator
|
||||
$i = strpos($data, ';', $i);
|
||||
if ($i === false) {
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
/* array */
|
||||
// find array start
|
||||
$i = strpos($data, '{', $i);
|
||||
if ($i === false) {
|
||||
return null;
|
||||
}
|
||||
// remember nesting
|
||||
$depth++;
|
||||
break;
|
||||
case 'N':
|
||||
/* null */
|
||||
// skip to end
|
||||
$i = strpos($data, ';', $i);
|
||||
if ($i === false) {
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* any other elements are not wanted */
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// check unterminated arrays
|
||||
if ($depth > 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return unserialize($data);
|
||||
}
|
||||
?>
|
||||
|
||||
@ -139,11 +139,11 @@ function PMA_DBI_DBG_query($query, $link, $result, $time)
|
||||
} else {
|
||||
$_SESSION['debug']['queries'][$hash] = array();
|
||||
if ($result == false) {
|
||||
$_SESSION['debug']['queries'][$hash]['error']
|
||||
= '<b style="color:red">' . mysqli_error($link) . '</b>';
|
||||
$_SESSION['debug']['queries'][$hash]['error'] = '<b style="color:red">'
|
||||
. htmlspecialchars(mysqli_error($link)) . '</b>';
|
||||
}
|
||||
$_SESSION['debug']['queries'][$hash]['count'] = 1;
|
||||
$_SESSION['debug']['queries'][$hash]['query'] = $query;
|
||||
$_SESSION['debug']['queries'][$hash]['query'] = htmlspecialchars($query);
|
||||
$_SESSION['debug']['queries'][$hash]['time'] = $time;
|
||||
}
|
||||
|
||||
@ -1567,11 +1567,22 @@ function PMA_DBI_postConnect($link, $is_controluser = false)
|
||||
PMA_DBI_query("SET CHARACTER SET 'utf8';", $link, PMA_DBI_QUERY_STORE);
|
||||
$set_collation_con_query = "SET collation_connection = '"
|
||||
. PMA_Util::sqlAddSlashes($GLOBALS['collation_connection']) . "';";
|
||||
PMA_DBI_query(
|
||||
$result = PMA_DBI_try_query(
|
||||
$set_collation_con_query,
|
||||
$link,
|
||||
PMA_DBI_QUERY_STORE
|
||||
);
|
||||
if ($result === false) {
|
||||
trigger_error(
|
||||
__('Failed to set configured collation connection!'),
|
||||
E_USER_WARNING
|
||||
);
|
||||
$result = PMA_DBI_query(
|
||||
"SET collation_connection = 'utf8_general_ci'",
|
||||
$link,
|
||||
PMA_DBI_QUERY_STORE
|
||||
);
|
||||
}
|
||||
} else {
|
||||
PMA_DBI_query(
|
||||
"SET NAMES 'utf8' COLLATE 'utf8_general_ci';",
|
||||
|
||||
@ -258,6 +258,18 @@ $GLOBALS['dummy_queries'] = array(
|
||||
'query' => 'SHOW TABLES FROM `pma`;',
|
||||
'result' => array(),
|
||||
),
|
||||
array(
|
||||
'query' => 'SHOW TABLES FROM `mysql`;',
|
||||
'result' => array(),
|
||||
),
|
||||
array(
|
||||
'query' => "SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`SCHEMA_PRIVILEGES` WHERE GRANTEE='''pma_test''@''localhost''' AND PRIVILEGE_TYPE='TRIGGER' AND 'mysql' REGEXP REPLACE(REPLACE(TABLE_SCHEMA, '_', '.'), '%', '.*')",
|
||||
'result' => array(),
|
||||
),
|
||||
array(
|
||||
'query' => "SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`SCHEMA_PRIVILEGES` WHERE GRANTEE='''pma_test''@''localhost''' AND PRIVILEGE_TYPE='EVENT' AND 'mysql' REGEXP REPLACE(REPLACE(TABLE_SCHEMA, '_', '.'), '%', '.*')",
|
||||
'result' => array(),
|
||||
),
|
||||
array(
|
||||
'query' => "SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`SCHEMA_PRIVILEGES` WHERE GRANTEE='''pma_test''@''localhost''' AND PRIVILEGE_TYPE='EVENT' AND TABLE_SCHEMA='pma'",
|
||||
'result' => array(),
|
||||
|
||||
@ -114,10 +114,12 @@ function PMA_DBI_connect(
|
||||
|
||||
$client_flags = 0;
|
||||
|
||||
// always use CLIENT_LOCAL_FILES as defined in mysql_com.h
|
||||
if (defined('PMA_ENABLE_LDI')) {
|
||||
// use CLIENT_LOCAL_FILES as defined in mysql_com.h
|
||||
// for the case where the client library was not compiled
|
||||
// with --enable-local-infile
|
||||
$client_flags |= 128;
|
||||
}
|
||||
|
||||
/* Optionally compress connection */
|
||||
if (defined('MYSQL_CLIENT_COMPRESS') && $cfg['Server']['compress']) {
|
||||
|
||||
@ -147,7 +147,11 @@ function PMA_DBI_connect(
|
||||
|
||||
$link = mysqli_init();
|
||||
|
||||
if (defined('PMA_ENABLE_LDI')) {
|
||||
mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, true);
|
||||
} else {
|
||||
mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, false);
|
||||
}
|
||||
|
||||
$client_flags = 0;
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ if ($is_create_db_priv) {
|
||||
. PMA_Util::showMySQLDocu('SQL-Syntax', 'CREATE_DATABASE'); ?></strong><br />
|
||||
<?php echo PMA_generate_common_hidden_inputs('', '', 5); ?>
|
||||
<input type="hidden" name="reload" value="1" />
|
||||
<input type="text" name="new_db" value="<?php echo $db_to_create; ?>" maxlength="64" class="textfield" id="text_create_db"/>
|
||||
<input type="text" name="new_db" value="<?php echo htmlspecialchars($db_to_create); ?>" maxlength="64" class="textfield" id="text_create_db"/>
|
||||
<?php
|
||||
include_once './libraries/mysql_charsets.lib.php';
|
||||
echo PMA_generateCharsetDropdownBox(PMA_CSDROPDOWN_COLLATION, 'db_collation', null, null, true, 5);
|
||||
|
||||
@ -40,7 +40,7 @@ function PMA_printGitRevision()
|
||||
'https://github.com/phpmyadmin/phpmyadmin/commit/'
|
||||
. $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_COMMITHASH')
|
||||
)
|
||||
. '" target="_blank">' . $commit_hash . '</a>';
|
||||
. '" rel="noopener noreferrer" target="_blank">' . $commit_hash . '</a>';
|
||||
}
|
||||
|
||||
$branch = $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_BRANCH');
|
||||
@ -50,7 +50,7 @@ function PMA_printGitRevision()
|
||||
'https://github.com/phpmyadmin/phpmyadmin/tree/'
|
||||
. $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_BRANCH')
|
||||
)
|
||||
. '" target="_blank">' . $branch . '</a>';
|
||||
. '" rel="noopener noreferrer" target="_blank">' . $branch . '</a>';
|
||||
}
|
||||
if ($branch !== false) {
|
||||
$branch = sprintf(__('%1$s from %2$s branch'), $commit_hash, $branch);
|
||||
|
||||
@ -132,11 +132,11 @@ class PMA_StorageEngine_pbxt extends PMA_StorageEngine
|
||||
function getPageDocumentation()
|
||||
{
|
||||
$output = '<p>'
|
||||
. sprintf(__('Documentation and further information about PBXT can be found on the %sPrimeBase XT Home Page%s.'), '<a href="' . PMA_linkURL('http://www.primebase.com/xt/') . '" target="_blank">', '</a>')
|
||||
. sprintf(__('Documentation and further information about PBXT can be found on the %sPrimeBase XT Home Page%s.'), '<a href="' . PMA_linkURL('http://www.primebase.com/xt/') . '" rel="noopener noreferrer" target="_blank">', '</a>')
|
||||
. '</p>' . "\n"
|
||||
. '<h3>' . __('Related Links') . '</h3>' . "\n"
|
||||
. '<ul>' . "\n"
|
||||
. '<li><a href="' . PMA_linkURL('http://pbxt.blogspot.com/') . '" target="_blank">' . __('The PrimeBase XT Blog by Paul McCullagh') . '</a></li>' . "\n"
|
||||
. '<li><a href="' . PMA_linkURL('http://pbxt.blogspot.com/') . '" rel="noopener noreferrer" target="_blank">' . __('The PrimeBase XT Blog by Paul McCullagh') . '</a></li>' . "\n"
|
||||
. '</ul>' . "\n";
|
||||
|
||||
return $output;
|
||||
|
||||
@ -30,6 +30,7 @@ function PMA_getDirContent($dir, $expression = '')
|
||||
if ('.' != $file
|
||||
&& '..' != $file
|
||||
&& is_file($dir . $file)
|
||||
&& ! is_link($dir . $file)
|
||||
&& ($expression == '' || preg_match($expression, $file))
|
||||
) {
|
||||
$result[] = $file;
|
||||
|
||||
@ -31,7 +31,9 @@ class PMA_GIS_Factory
|
||||
include_once './libraries/gis/pma_gis_geometry.php';
|
||||
|
||||
$type_lower = strtolower($type);
|
||||
if (! file_exists('./libraries/gis/pma_gis_' . $type_lower . '.php')) {
|
||||
if (! PMA_isValid($type_lower, PMA_Util::getGISDatatypes())
|
||||
|| ! file_exists('./libraries/gis/pma_gis_' . $type_lower . '.php')
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (include_once './libraries/gis/pma_gis_' . $type_lower . '.php') {
|
||||
|
||||
@ -117,11 +117,11 @@ abstract class PMA_GIS_Geometry
|
||||
. 'bound.extend(new OpenLayers.LonLat('
|
||||
. $scale_data['minX'] . ', ' . $scale_data['minY']
|
||||
. ').transform(new OpenLayers.Projection("EPSG:'
|
||||
. $srid . '"), map.getProjectionObject())); '
|
||||
. intval($srid) . '"), map.getProjectionObject())); '
|
||||
. 'bound.extend(new OpenLayers.LonLat('
|
||||
. $scale_data['maxX'] . ', ' . $scale_data['maxY']
|
||||
. ').transform(new OpenLayers.Projection("EPSG:'
|
||||
. $srid . '"), map.getProjectionObject()));';
|
||||
. intval($srid) . '"), map.getProjectionObject()));';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -215,8 +215,8 @@ abstract class PMA_GIS_Geometry
|
||||
$y = $scale_data['height']
|
||||
- ($cordinates[1] - $scale_data['y']) * $scale_data['scale'];
|
||||
} else {
|
||||
$x = trim($cordinates[0]);
|
||||
$y = trim($cordinates[1]);
|
||||
$x = floatval(trim($cordinates[0]));
|
||||
$y = floatval(trim($cordinates[1]));
|
||||
}
|
||||
} else {
|
||||
$x = '';
|
||||
@ -355,7 +355,7 @@ abstract class PMA_GIS_Geometry
|
||||
{
|
||||
return '(new OpenLayers.Geometry.Point(' . $point[0] . ',' . $point[1] . '))'
|
||||
. '.transform(new OpenLayers.Projection("EPSG:'
|
||||
. $srid . '"), map.getProjectionObject())';
|
||||
. intval($srid) . '"), map.getProjectionObject())';
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@ -802,7 +802,7 @@ function PMA_detectType($last_cumulative_type, $cell)
|
||||
* @return array array(array $types, array $sizes)
|
||||
* @access public
|
||||
*
|
||||
* @link http://wiki.phpmyadmin.net/pma/Import
|
||||
* @link https://wiki.phpmyadmin.net/pma/Import
|
||||
*
|
||||
* @todo Handle the error case more elegantly
|
||||
*/
|
||||
@ -911,7 +911,7 @@ $import_notice = null;
|
||||
* @return void
|
||||
* @access public
|
||||
*
|
||||
* @link http://wiki.phpmyadmin.net/pma/Import
|
||||
* @link https://wiki.phpmyadmin.net/pma/Import
|
||||
*/
|
||||
function PMA_buildSQL($db_name, &$tables, &$analyses = null,
|
||||
&$additional_sql = null, $options = null
|
||||
|
||||
@ -29,19 +29,29 @@ function PMA_getIp()
|
||||
|
||||
/* Do we trust this IP as a proxy? If yes we will use it's header. */
|
||||
if (isset($GLOBALS['cfg']['TrustedProxies'][$direct_ip])) {
|
||||
$trusted_header_value
|
||||
= PMA_getenv($GLOBALS['cfg']['TrustedProxies'][$direct_ip]);
|
||||
$matches = array();
|
||||
/**
|
||||
* Parse header in form:
|
||||
* X-Forwarded-For: client, proxy1, proxy2
|
||||
*/
|
||||
// Get header content
|
||||
$value = PMA_getenv($GLOBALS['cfg']['TrustedProxies'][$direct_ip]);
|
||||
// Grab first element what is client adddress
|
||||
$values = explode(',', $value);
|
||||
$value = $values[0];
|
||||
// Extract IP address
|
||||
// the $ checks that the header contains only one IP address,
|
||||
// ?: makes sure the () don't capture
|
||||
$matches = array();
|
||||
$is_ip = preg_match(
|
||||
'|^(?:[0-9]{1,3}\.){3,3}[0-9]{1,3}$|',
|
||||
$trusted_header_value, $matches
|
||||
$value, $matches
|
||||
);
|
||||
if ($is_ip && (count($matches) == 1)) {
|
||||
// True IP behind a proxy
|
||||
return $matches[0];
|
||||
}
|
||||
// We could not parse header
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return true IP */
|
||||
@ -182,7 +192,7 @@ function PMA_ipv6MaskTest($test_range, $ip_to_test)
|
||||
|
||||
if ($is_single) {
|
||||
$range_hex = bin2hex(inet_pton($test_range));
|
||||
$result = $ip_hex === $range_hex;
|
||||
$result = hash_equals($ip_hex, $range_hex);
|
||||
} elseif ($is_range) {
|
||||
// what range do we operate on?
|
||||
$range_match = array();
|
||||
@ -296,7 +306,7 @@ function PMA_allowDeny($type)
|
||||
|
||||
// check for username
|
||||
if (($rule_data[1] != '%') //wildcarded first
|
||||
&& ($rule_data[1] != $username)
|
||||
&& (! hash_equals($rule_data[1], $username))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -170,12 +170,14 @@ if (!empty($submit_mult) && !empty($what)) {
|
||||
foreach ($selected AS $idx => $sval) {
|
||||
switch ($what) {
|
||||
case 'row_delete':
|
||||
$full_query .= 'DELETE FROM ' . PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table)
|
||||
$full_query .= 'DELETE FROM '
|
||||
. PMA_Util::backquote(htmlspecialchars($db))
|
||||
. '.' . PMA_Util::backquote(htmlspecialchars($table))
|
||||
// Do not append a "LIMIT 1" clause here
|
||||
// (it's not binlog friendly).
|
||||
// We don't need the clause because the calling panel permits
|
||||
// this feature only when there is a unique index.
|
||||
. ' WHERE ' . urldecode($sval)
|
||||
. ' WHERE ' . htmlspecialchars(urldecode($sval))
|
||||
. ';<br />';
|
||||
break;
|
||||
case 'drop_db':
|
||||
|
||||
@ -82,10 +82,9 @@ class PMA_NavigationHeader
|
||||
$retval .= '<div id="pmalogo">';
|
||||
if ($GLOBALS['cfg']['NavigationLogoLink']) {
|
||||
$logo_link = trim(htmlspecialchars($GLOBALS['cfg']['NavigationLogoLink']));
|
||||
// prevent XSS, see PMASA-2013-9
|
||||
// if link has protocol, allow only http and https
|
||||
if (preg_match('/^[a-z]+:/i', $logo_link)
|
||||
&& ! preg_match('/^https?:/i', $logo_link)) {
|
||||
$parsed = parse_url($logo_link);
|
||||
/* Allow only links with http/https */
|
||||
if (! isset($parsed['scheme']) || ! in_array(strtolower($parsed['scheme']), array('http', 'https'))) {
|
||||
$logo_link = 'index.php';
|
||||
}
|
||||
$retval .= ' <a href="' . $logo_link;
|
||||
|
||||
@ -283,7 +283,7 @@ class Node
|
||||
$retval = true;
|
||||
} else {
|
||||
foreach ($this->parent->children as $child) {
|
||||
if ($child != $this
|
||||
if ($child !== $this
|
||||
&& ($child->type == Node::OBJECT || $child->hasChildren(false))
|
||||
) {
|
||||
$retval = true;
|
||||
|
||||
@ -350,6 +350,10 @@ class gettext_reader {
|
||||
* @return int array index of the right plural form
|
||||
*/
|
||||
function select_string($n) {
|
||||
if (!is_int($n)) {
|
||||
throw new InvalidArgumentException(
|
||||
"Select_string only accepts integers: " . $n);
|
||||
}
|
||||
$string = $this->get_plural_forms();
|
||||
$string = str_replace('nplurals',"\$total",$string);
|
||||
$string = str_replace("n",$n,$string);
|
||||
|
||||
299
libraries/phpseclib/Crypt/Random.php
Normal file
299
libraries/phpseclib/Crypt/Random.php
Normal file
@ -0,0 +1,299 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Random Number Generator
|
||||
*
|
||||
* The idea behind this function is that it can be easily replaced with your own crypt_random_string()
|
||||
* function. eg. maybe you have a better source of entropy for creating the initial states or whatever.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include 'Crypt/Random.php';
|
||||
*
|
||||
* echo bin2hex(crypt_random_string(8));
|
||||
* ?>
|
||||
* </code>
|
||||
*
|
||||
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @category Crypt
|
||||
* @package Crypt_Random
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2007 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
// laravel is a PHP framework that utilizes phpseclib. laravel workbenches may, independently,
|
||||
// have phpseclib as a requirement as well. if you're developing such a program you may encounter
|
||||
// a "Cannot redeclare crypt_random_string()" error.
|
||||
if (!function_exists('crypt_random_string')) {
|
||||
/**
|
||||
* "Is Windows" test
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
define('CRYPT_RANDOM_IS_WINDOWS', strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
|
||||
|
||||
/**
|
||||
* Generate a random string.
|
||||
*
|
||||
* Although microoptimizations are generally discouraged as they impair readability this function is ripe with
|
||||
* microoptimizations because this function has the potential of being called a huge number of times.
|
||||
* eg. for RSA key generation.
|
||||
*
|
||||
* @param int $length
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function crypt_random_string($length)
|
||||
{
|
||||
if (CRYPT_RANDOM_IS_WINDOWS) {
|
||||
// method 1. prior to PHP 5.3, mcrypt_create_iv() would call rand() on windows
|
||||
if (extension_loaded('mcrypt') && version_compare(PHP_VERSION, '5.3.0', '>=')) {
|
||||
return mcrypt_create_iv($length);
|
||||
}
|
||||
// method 2. openssl_random_pseudo_bytes was introduced in PHP 5.3.0 but prior to PHP 5.3.4 there was,
|
||||
// to quote <http://php.net/ChangeLog-5.php#5.3.4>, "possible blocking behavior". as of 5.3.4
|
||||
// openssl_random_pseudo_bytes and mcrypt_create_iv do the exact same thing on Windows. ie. they both
|
||||
// call php_win32_get_random_bytes():
|
||||
//
|
||||
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/openssl/openssl.c#L5008
|
||||
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1392
|
||||
//
|
||||
// php_win32_get_random_bytes() is defined thusly:
|
||||
//
|
||||
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/win32/winutil.c#L80
|
||||
//
|
||||
// we're calling it, all the same, in the off chance that the mcrypt extension is not available
|
||||
if (extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.4', '>=')) {
|
||||
return openssl_random_pseudo_bytes($length);
|
||||
}
|
||||
} else {
|
||||
// method 1. the fastest
|
||||
if (extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.0', '>=')) {
|
||||
return openssl_random_pseudo_bytes($length);
|
||||
}
|
||||
// method 2
|
||||
static $fp = true;
|
||||
if ($fp === true) {
|
||||
// warning's will be output unles the error suppression operator is used. errors such as
|
||||
// "open_basedir restriction in effect", "Permission denied", "No such file or directory", etc.
|
||||
$fp = @fopen('/dev/urandom', 'rb');
|
||||
}
|
||||
if ($fp !== true && $fp !== false) { // surprisingly faster than !is_bool() or is_resource()
|
||||
return fread($fp, $length);
|
||||
}
|
||||
// method 3. pretty much does the same thing as method 2 per the following url:
|
||||
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1391
|
||||
// surprisingly slower than method 2. maybe that's because mcrypt_create_iv does a bunch of error checking that we're
|
||||
// not doing. regardless, this'll only be called if this PHP script couldn't open /dev/urandom due to open_basedir
|
||||
// restrictions or some such
|
||||
if (extension_loaded('mcrypt')) {
|
||||
return mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
|
||||
}
|
||||
}
|
||||
// at this point we have no choice but to use a pure-PHP CSPRNG
|
||||
|
||||
// cascade entropy across multiple PHP instances by fixing the session and collecting all
|
||||
// environmental variables, including the previous session data and the current session
|
||||
// data.
|
||||
//
|
||||
// mt_rand seeds itself by looking at the PID and the time, both of which are (relatively)
|
||||
// easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but
|
||||
// PHP isn't low level to be able to use those as sources and on a web server there's not likely
|
||||
// going to be a ton of keyboard or mouse action. web servers do have one thing that we can use
|
||||
// however, a ton of people visiting the website. obviously you don't want to base your seeding
|
||||
// soley on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled
|
||||
// by the user and (2) this isn't just looking at the data sent by the current user - it's based
|
||||
// on the data sent by all users. one user requests the page and a hash of their info is saved.
|
||||
// another user visits the page and the serialization of their data is utilized along with the
|
||||
// server envirnment stuff and a hash of the previous http request data (which itself utilizes
|
||||
// a hash of the session data before that). certainly an attacker should be assumed to have
|
||||
// full control over his own http requests. he, however, is not going to have control over
|
||||
// everyone's http requests.
|
||||
static $crypto = false, $v;
|
||||
if ($crypto === false) {
|
||||
// save old session data
|
||||
$old_session_id = session_id();
|
||||
$old_use_cookies = ini_get('session.use_cookies');
|
||||
$old_session_cache_limiter = session_cache_limiter();
|
||||
$_OLD_SESSION = isset($_SESSION) ? $_SESSION : false;
|
||||
if ($old_session_id != '') {
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
session_id(1);
|
||||
ini_set('session.use_cookies', 0);
|
||||
session_cache_limiter('');
|
||||
session_start();
|
||||
|
||||
$v = $seed = $_SESSION['seed'] = pack('H*', sha1(
|
||||
serialize($_SERVER) .
|
||||
serialize($_POST) .
|
||||
serialize($_GET) .
|
||||
serialize($_COOKIE) .
|
||||
serialize($GLOBALS) .
|
||||
serialize($_SESSION) .
|
||||
serialize($_OLD_SESSION)
|
||||
));
|
||||
if (!isset($_SESSION['count'])) {
|
||||
$_SESSION['count'] = 0;
|
||||
}
|
||||
$_SESSION['count']++;
|
||||
|
||||
session_write_close();
|
||||
|
||||
// restore old session data
|
||||
if ($old_session_id != '') {
|
||||
session_id($old_session_id);
|
||||
session_start();
|
||||
ini_set('session.use_cookies', $old_use_cookies);
|
||||
session_cache_limiter($old_session_cache_limiter);
|
||||
} else {
|
||||
if ($_OLD_SESSION !== false) {
|
||||
$_SESSION = $_OLD_SESSION;
|
||||
unset($_OLD_SESSION);
|
||||
} else {
|
||||
unset($_SESSION);
|
||||
}
|
||||
}
|
||||
|
||||
// in SSH2 a shared secret and an exchange hash are generated through the key exchange process.
|
||||
// the IV client to server is the hash of that "nonce" with the letter A and for the encryption key it's the letter C.
|
||||
// if the hash doesn't produce enough a key or an IV that's long enough concat successive hashes of the
|
||||
// original hash and the current hash. we'll be emulating that. for more info see the following URL:
|
||||
//
|
||||
// http://tools.ietf.org/html/rfc4253#section-7.2
|
||||
//
|
||||
// see the is_string($crypto) part for an example of how to expand the keys
|
||||
$key = pack('H*', sha1($seed . 'A'));
|
||||
$iv = pack('H*', sha1($seed . 'C'));
|
||||
|
||||
// ciphers are used as per the nist.gov link below. also, see this link:
|
||||
//
|
||||
// http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives
|
||||
switch (true) {
|
||||
case phpseclib_resolve_include_path('Crypt/AES.php'):
|
||||
if (!class_exists('Crypt_AES')) {
|
||||
include_once 'AES.php';
|
||||
}
|
||||
$crypto = new Crypt_AES(CRYPT_AES_MODE_CTR);
|
||||
break;
|
||||
case phpseclib_resolve_include_path('Crypt/Twofish.php'):
|
||||
if (!class_exists('Crypt_Twofish')) {
|
||||
include_once 'Twofish.php';
|
||||
}
|
||||
$crypto = new Crypt_Twofish(CRYPT_TWOFISH_MODE_CTR);
|
||||
break;
|
||||
case phpseclib_resolve_include_path('Crypt/Blowfish.php'):
|
||||
if (!class_exists('Crypt_Blowfish')) {
|
||||
include_once 'Blowfish.php';
|
||||
}
|
||||
$crypto = new Crypt_Blowfish(CRYPT_BLOWFISH_MODE_CTR);
|
||||
break;
|
||||
case phpseclib_resolve_include_path('Crypt/TripleDES.php'):
|
||||
if (!class_exists('Crypt_TripleDES')) {
|
||||
include_once 'TripleDES.php';
|
||||
}
|
||||
$crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
|
||||
break;
|
||||
case phpseclib_resolve_include_path('Crypt/DES.php'):
|
||||
if (!class_exists('Crypt_DES')) {
|
||||
include_once 'DES.php';
|
||||
}
|
||||
$crypto = new Crypt_DES(CRYPT_DES_MODE_CTR);
|
||||
break;
|
||||
case phpseclib_resolve_include_path('Crypt/RC4.php'):
|
||||
if (!class_exists('Crypt_RC4')) {
|
||||
include_once 'RC4.php';
|
||||
}
|
||||
$crypto = new Crypt_RC4();
|
||||
break;
|
||||
default:
|
||||
user_error('crypt_random_string requires at least one symmetric cipher be loaded');
|
||||
return false;
|
||||
}
|
||||
|
||||
$crypto->setKey($key);
|
||||
$crypto->setIV($iv);
|
||||
$crypto->enableContinuousBuffer();
|
||||
}
|
||||
|
||||
//return $crypto->encrypt(str_repeat("\0", $length));
|
||||
|
||||
// the following is based off of ANSI X9.31:
|
||||
//
|
||||
// http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
|
||||
//
|
||||
// OpenSSL uses that same standard for it's random numbers:
|
||||
//
|
||||
// http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c
|
||||
// (do a search for "ANS X9.31 A.2.4")
|
||||
$result = '';
|
||||
while (strlen($result) < $length) {
|
||||
$i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21
|
||||
$r = $crypto->encrypt($i ^ $v); // strlen($v) == 20
|
||||
$v = $crypto->encrypt($r ^ $i); // strlen($r) == 20
|
||||
$result.= $r;
|
||||
}
|
||||
return substr($result, 0, $length);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('phpseclib_resolve_include_path')) {
|
||||
/**
|
||||
* Resolve filename against the include path.
|
||||
*
|
||||
* Wrapper around stream_resolve_include_path() (which was introduced in
|
||||
* PHP 5.3.2) with fallback implementation for earlier PHP versions.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return string|false
|
||||
* @access public
|
||||
*/
|
||||
function phpseclib_resolve_include_path($filename)
|
||||
{
|
||||
if (function_exists('stream_resolve_include_path')) {
|
||||
return stream_resolve_include_path($filename);
|
||||
}
|
||||
|
||||
// handle non-relative paths
|
||||
if (file_exists($filename)) {
|
||||
return realpath($filename);
|
||||
}
|
||||
|
||||
$paths = PATH_SEPARATOR == ':' ?
|
||||
preg_split('#(?<!phar):#', get_include_path()) :
|
||||
explode(PATH_SEPARATOR, get_include_path());
|
||||
foreach ($paths as $prefix) {
|
||||
// path's specified in include_path don't always end in /
|
||||
$ds = substr($prefix, -1) == DIRECTORY_SEPARATOR ? '' : DIRECTORY_SEPARATOR;
|
||||
$file = $prefix . $ds . $filename;
|
||||
if (file_exists($file)) {
|
||||
return realpath($file);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -31,8 +31,10 @@ function PMA_getPlugin(
|
||||
$file = $class_name . ".class.php";
|
||||
if (is_file($plugins_dir . $file)) {
|
||||
include_once $plugins_dir . $file;
|
||||
if (class_exists($class_name)) {
|
||||
return new $class_name;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -41,6 +41,15 @@ abstract class AuthenticationPlugin extends PluginObserver
|
||||
*/
|
||||
abstract public function authSetUser();
|
||||
|
||||
/**
|
||||
* Stores user credentials after successful login.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function storeUserCredentials()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* User is not allowed to login to MySQL -> authentication failed
|
||||
*
|
||||
|
||||
@ -23,11 +23,6 @@ if (! empty($_REQUEST['target'])) {
|
||||
$GLOBALS['target'] = basename(PMA_getenv('SCRIPT_NAME'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Swekey authentication functions.
|
||||
*/
|
||||
require './libraries/plugins/auth/swekey/swekey.auth.lib.php';
|
||||
|
||||
/**
|
||||
* Initialization
|
||||
* Store the initialization vector because it will be needed for
|
||||
@ -143,7 +138,7 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
echo '
|
||||
<div class="container">
|
||||
<a href="';
|
||||
echo PMA_linkURL('http://www.phpmyadmin.net/');
|
||||
echo PMA_linkURL('https://www.phpmyadmin.net/');
|
||||
echo '" target="_blank" class="logo">';
|
||||
$logo_image = $GLOBALS['pmaThemeImage'] . 'logo_right.png';
|
||||
if (@file_exists($logo_image)) {
|
||||
@ -258,10 +253,6 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
echo '</fieldset>
|
||||
</form>';
|
||||
|
||||
// BEGIN Swekey Integration
|
||||
Swekey_login('input_username', 'input_go');
|
||||
// END Swekey Integration
|
||||
|
||||
if ($GLOBALS['error_handler']->hasDisplayErrors()) {
|
||||
echo '<div>';
|
||||
$GLOBALS['error_handler']->dispErrors();
|
||||
@ -306,16 +297,9 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
$GLOBALS['PHP_AUTH_USER'] = $GLOBALS['PHP_AUTH_PW'] = '';
|
||||
$GLOBALS['from_cookie'] = false;
|
||||
|
||||
// BEGIN Swekey Integration
|
||||
if (! Swekey_auth_check()) {
|
||||
return false;
|
||||
}
|
||||
// END Swekey Integration
|
||||
|
||||
if (defined('PMA_CLEAR_COOKIES')) {
|
||||
foreach ($GLOBALS['cfg']['Servers'] as $key => $val) {
|
||||
$GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $key);
|
||||
$GLOBALS['PMA_Config']->removeCookie('pmaServer-' . $key);
|
||||
$GLOBALS['PMA_Config']->removeCookie('pmaAuth-' . $key);
|
||||
$GLOBALS['PMA_Config']->removeCookie('pmaUser-' . $key);
|
||||
}
|
||||
return false;
|
||||
@ -332,31 +316,31 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
// -> delete password cookie(s)
|
||||
if ($GLOBALS['cfg']['LoginCookieDeleteAll']) {
|
||||
foreach ($GLOBALS['cfg']['Servers'] as $key => $val) {
|
||||
$GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $key);
|
||||
if (isset($_COOKIE['pmaPass-' . $key])) {
|
||||
unset($_COOKIE['pmaPass-' . $key]);
|
||||
$GLOBALS['PMA_Config']->removeCookie('pmaAuth-' . $key);
|
||||
if (isset($_COOKIE['pmaAuth-' . $key])) {
|
||||
unset($_COOKIE['pmaAuth-' . $key]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$GLOBALS['PMA_Config']->removeCookie(
|
||||
'pmaPass-' . $GLOBALS['server']
|
||||
'pmaAuth-' . $GLOBALS['server']
|
||||
);
|
||||
if (isset($_COOKIE['pmaPass-' . $GLOBALS['server']])) {
|
||||
unset($_COOKIE['pmaPass-' . $GLOBALS['server']]);
|
||||
if (isset($_COOKIE['pmaAuth-' . $GLOBALS['server']])) {
|
||||
unset($_COOKIE['pmaAuth-' . $GLOBALS['server']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! empty($_REQUEST['pma_username'])) {
|
||||
// The user just logged in
|
||||
$GLOBALS['PHP_AUTH_USER'] = $_REQUEST['pma_username'];
|
||||
$GLOBALS['PHP_AUTH_USER'] = PMA_sanitizeMySQLUser($_REQUEST['pma_username']);
|
||||
$GLOBALS['PHP_AUTH_PW'] = empty($_REQUEST['pma_password'])
|
||||
? ''
|
||||
: $_REQUEST['pma_password'];
|
||||
if ($GLOBALS['cfg']['AllowArbitraryServer']
|
||||
&& isset($_REQUEST['pma_servername'])
|
||||
) {
|
||||
$GLOBALS['pma_auth_server'] = $_REQUEST['pma_servername'];
|
||||
$GLOBALS['pma_auth_server'] = PMA_sanitizeMySQLHost($_REQUEST['pma_servername']);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -364,22 +348,14 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
// At the end, try to set the $GLOBALS['PHP_AUTH_USER']
|
||||
// and $GLOBALS['PHP_AUTH_PW'] variables from cookies
|
||||
|
||||
// servername
|
||||
if ($GLOBALS['cfg']['AllowArbitraryServer']
|
||||
&& ! empty($_COOKIE['pmaServer-' . $GLOBALS['server']])
|
||||
) {
|
||||
$GLOBALS['pma_auth_server']
|
||||
= $_COOKIE['pmaServer-' . $GLOBALS['server']];
|
||||
}
|
||||
|
||||
// username
|
||||
// check cookies
|
||||
if (empty($_COOKIE['pmaUser-' . $GLOBALS['server']])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$GLOBALS['PHP_AUTH_USER'] = $this->blowfishDecrypt(
|
||||
$GLOBALS['PHP_AUTH_USER'] = $this->cookieDecrypt(
|
||||
$_COOKIE['pmaUser-' . $GLOBALS['server']],
|
||||
$this->_getBlowfishSecret()
|
||||
$this->_getEncryptionSecret()
|
||||
);
|
||||
|
||||
// user was never logged in since session start
|
||||
@ -401,18 +377,24 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
exit;
|
||||
}
|
||||
|
||||
// password
|
||||
if (empty($_COOKIE['pmaPass-' . $GLOBALS['server']])) {
|
||||
// check password cookie
|
||||
if (empty($_COOKIE['pmaAuth-' . $GLOBALS['server']])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$GLOBALS['PHP_AUTH_PW'] = $this->blowfishDecrypt(
|
||||
$_COOKIE['pmaPass-' . $GLOBALS['server']],
|
||||
$this->_getBlowfishSecret()
|
||||
$auth_data = json_decode(
|
||||
$this->cookieDecrypt(
|
||||
$_COOKIE['pmaAuth-' . $GLOBALS['server']],
|
||||
$this->_getSessionEncryptionSecret()
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
if ($GLOBALS['PHP_AUTH_PW'] == "\xff(blank)") {
|
||||
$GLOBALS['PHP_AUTH_PW'] = '';
|
||||
if (! is_array($auth_data) || ! isset($auth_data['password'])) {
|
||||
return false;
|
||||
}
|
||||
$GLOBALS['PHP_AUTH_PW'] = $auth_data['password'];
|
||||
if ($GLOBALS['cfg']['AllowArbitraryServer'] && ! empty($auth_data['server'])) {
|
||||
$GLOBALS['pma_auth_server'] = $auth_data['server'];
|
||||
}
|
||||
|
||||
$GLOBALS['from_cookie'] = true;
|
||||
@ -431,14 +413,14 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
|
||||
// Ensures valid authentication mode, 'only_db', bookmark database and
|
||||
// table names and relation table name are used
|
||||
if ($cfg['Server']['user'] != $GLOBALS['PHP_AUTH_USER']) {
|
||||
if (! hash_equals($cfg['Server']['user'], $GLOBALS['PHP_AUTH_USER'])) {
|
||||
foreach ($cfg['Servers'] as $idx => $current) {
|
||||
if ($current['host'] == $cfg['Server']['host']
|
||||
&& $current['port'] == $cfg['Server']['port']
|
||||
&& $current['socket'] == $cfg['Server']['socket']
|
||||
&& $current['ssl'] == $cfg['Server']['ssl']
|
||||
&& $current['connect_type'] == $cfg['Server']['connect_type']
|
||||
&& $current['user'] == $GLOBALS['PHP_AUTH_USER']
|
||||
&& hash_equals($current['user'], $GLOBALS['PHP_AUTH_USER'])
|
||||
) {
|
||||
$GLOBALS['server'] = $idx;
|
||||
$cfg['Server'] = $current;
|
||||
@ -475,47 +457,26 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
unset($_SERVER['PHP_AUTH_PW']);
|
||||
|
||||
$_SESSION['last_access_time'] = time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores user credentials after successful login.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function storeUserCredentials()
|
||||
{
|
||||
global $cfg;
|
||||
|
||||
// Name and password cookies need to be refreshed each time
|
||||
// Duration = one month for username
|
||||
$GLOBALS['PMA_Config']->setCookie(
|
||||
'pmaUser-' . $GLOBALS['server'],
|
||||
$this->blowfishEncrypt(
|
||||
$cfg['Server']['user'],
|
||||
$this->_getBlowfishSecret()
|
||||
)
|
||||
);
|
||||
|
||||
$this->storeUsernameCookie($cfg['Server']['user']);
|
||||
// Duration = as configured
|
||||
$GLOBALS['PMA_Config']->setCookie(
|
||||
'pmaPass-' . $GLOBALS['server'],
|
||||
$this->blowfishEncrypt(
|
||||
! empty($cfg['Server']['password'])
|
||||
? $cfg['Server']['password'] : "\xff(blank)",
|
||||
$this->_getBlowfishSecret()
|
||||
),
|
||||
null,
|
||||
$GLOBALS['cfg']['LoginCookieStore']
|
||||
);
|
||||
$this->storePasswordCookie($cfg['Server']['password']);
|
||||
|
||||
// Set server cookies if required (once per session) and, in this case,
|
||||
// force reload to ensure the client accepts cookies
|
||||
if (! $GLOBALS['from_cookie']) {
|
||||
if ($GLOBALS['cfg']['AllowArbitraryServer']) {
|
||||
if (! empty($GLOBALS['pma_auth_server'])) {
|
||||
// Duration = one month for servername
|
||||
$GLOBALS['PMA_Config']->setCookie(
|
||||
'pmaServer-' . $GLOBALS['server'],
|
||||
$cfg['Server']['host']
|
||||
);
|
||||
} else {
|
||||
// Delete servername cookie
|
||||
$GLOBALS['PMA_Config']->removeCookie(
|
||||
'pmaServer-' . $GLOBALS['server']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// URL where to go:
|
||||
$redirect_url = $cfg['PmaAbsoluteUri'] . 'index.php';
|
||||
|
||||
@ -549,7 +510,51 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
} // end if
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores username in a cookie.
|
||||
*
|
||||
* @param string $username User name
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function storeUsernameCookie($username)
|
||||
{
|
||||
// Name and password cookies need to be refreshed each time
|
||||
// Duration = one month for username
|
||||
$GLOBALS['PMA_Config']->setCookie(
|
||||
'pmaUser-' . $GLOBALS['server'],
|
||||
$this->cookieEncrypt(
|
||||
$username,
|
||||
$this->_getEncryptionSecret()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores password in a cookie.
|
||||
*
|
||||
* @param string $password Password
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function storePasswordCookie($password)
|
||||
{
|
||||
$payload = array('password' => $password);
|
||||
if ($GLOBALS['cfg']['AllowArbitraryServer'] && ! empty($GLOBALS['pma_auth_server'])) {
|
||||
$payload['server'] = $GLOBALS['pma_auth_server'];
|
||||
}
|
||||
// Duration = as configured
|
||||
$GLOBALS['PMA_Config']->setCookie(
|
||||
'pmaAuth-' . $GLOBALS['server'],
|
||||
$this->cookieEncrypt(
|
||||
json_encode($payload),
|
||||
$this->_getSessionEncryptionSecret()
|
||||
),
|
||||
null,
|
||||
$GLOBALS['cfg']['LoginCookieStore']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -568,7 +573,7 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
global $conn_error;
|
||||
|
||||
// Deletes password cookie and displays the login form
|
||||
$GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $GLOBALS['server']);
|
||||
$GLOBALS['PMA_Config']->removeCookie('pmaAuth-' . $GLOBALS['server']);
|
||||
|
||||
if (! empty($GLOBALS['login_without_password_is_forbidden'])) {
|
||||
$conn_error = __(
|
||||
@ -601,32 +606,120 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function _getBlowfishSecret()
|
||||
private function _getEncryptionSecret()
|
||||
{
|
||||
if (empty($GLOBALS['cfg']['blowfish_secret'])) {
|
||||
if (empty($_SESSION['auto_blowfish_secret'])) {
|
||||
// this returns 23 characters
|
||||
$_SESSION['auto_blowfish_secret'] = uniqid('', true);
|
||||
}
|
||||
return $_SESSION['auto_blowfish_secret'];
|
||||
return $this->_getSessionEncryptionSecret();
|
||||
} else {
|
||||
// apply md5() to work around too long secrets (returns 32 characters)
|
||||
return md5($GLOBALS['cfg']['blowfish_secret']);
|
||||
return $GLOBALS['cfg']['blowfish_secret'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encryption using blowfish algorithm (mcrypt)
|
||||
* or phpseclib's AES if mcrypt not available
|
||||
* Returns blowfish secret or generates one if needed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function _getSessionEncryptionSecret()
|
||||
{
|
||||
if (empty($_SESSION['encryption_key'])) {
|
||||
if ($this->_useOpenSSL()) {
|
||||
$_SESSION['encryption_key'] = openssl_random_pseudo_bytes(32);
|
||||
} else {
|
||||
include_once "./libraries/phpseclib/Crypt/Random.php";
|
||||
$_SESSION['encryption_key'] = crypt_random_string(32);
|
||||
}
|
||||
}
|
||||
return $_SESSION['encryption_key'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether we should use openssl for encryption.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function _useOpenSSL()
|
||||
{
|
||||
return (
|
||||
function_exists('openssl_encrypt')
|
||||
&& function_exists('openssl_decrypt')
|
||||
&& function_exists('openssl_random_pseudo_bytes')
|
||||
&& PHP_VERSION_ID >= 50304
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates secret in order to make it 16 bytes log
|
||||
*
|
||||
* This doesn't add any security, just ensures the secret
|
||||
* is long enough by copying it.
|
||||
*
|
||||
* @param string $secret Original secret
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function enlargeSecret($secret)
|
||||
{
|
||||
while (strlen($secret) < 16) {
|
||||
$secret .= $secret;
|
||||
}
|
||||
return substr($secret, 0, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives MAC secret from encryption secret.
|
||||
*
|
||||
* @param string $secret the secret
|
||||
*
|
||||
* @return string the MAC secret
|
||||
*/
|
||||
public function getMACSecret($secret)
|
||||
{
|
||||
// Grab first part, up to 16 chars
|
||||
// The MAC and AES secrets can overlap if original secret is short
|
||||
$length = strlen($secret);
|
||||
if ($length > 16) {
|
||||
return substr($secret, 0, 16);
|
||||
}
|
||||
return $this->enlargeSecret(
|
||||
$length == 1 ? $secret : substr($secret, 0, -1)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives AES secret from encryption secret.
|
||||
*
|
||||
* @param string $secret the secret
|
||||
*
|
||||
* @return string the AES secret
|
||||
*/
|
||||
public function getAESSecret($secret)
|
||||
{
|
||||
// Grab second part, up to 16 chars
|
||||
// The MAC and AES secrets can overlap if original secret is short
|
||||
$length = strlen($secret);
|
||||
if ($length > 16) {
|
||||
return substr($secret, -16);
|
||||
}
|
||||
return $this->enlargeSecret(
|
||||
$length == 1 ? $secret : substr($secret, 1)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encryption using openssl's AES or phpseclib's AES
|
||||
* (phpseclib uses mcrypt when it is available)
|
||||
*
|
||||
* @param string $data original data
|
||||
* @param string $secret the secret
|
||||
*
|
||||
* @return string the encrypted result
|
||||
*/
|
||||
public function blowfishEncrypt($data, $secret)
|
||||
public function cookieEncrypt($data, $secret)
|
||||
{
|
||||
global $iv;
|
||||
$mac_secret = $this->getMACSecret($secret);
|
||||
$aes_secret = $this->getAESSecret($secret);
|
||||
$iv = $this->createIV();
|
||||
if (! function_exists('mcrypt_encrypt')) {
|
||||
/**
|
||||
* This library uses mcrypt when available, so
|
||||
@ -636,10 +729,11 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
*/
|
||||
include_once "./libraries/phpseclib/Crypt/AES.php";
|
||||
$cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
|
||||
$cipher->setKey($secret);
|
||||
return base64_encode($cipher->encrypt($data));
|
||||
$cipher->setIV($iv);
|
||||
$cipher->setKey($aes_secret);
|
||||
$result = base64_encode($cipher->encrypt($data));
|
||||
} else {
|
||||
return base64_encode(
|
||||
$result = base64_encode(
|
||||
mcrypt_encrypt(
|
||||
MCRYPT_BLOWFISH,
|
||||
$secret,
|
||||
@ -649,6 +743,14 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
)
|
||||
);
|
||||
}
|
||||
$iv = base64_encode($iv);
|
||||
return json_encode(
|
||||
array(
|
||||
'iv' => $iv,
|
||||
'mac' => hash_hmac('sha1', $iv . $result, $mac_secret),
|
||||
'payload' => $result,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -658,29 +760,81 @@ class AuthenticationCookie extends AuthenticationPlugin
|
||||
* @param string $encdata encrypted data
|
||||
* @param string $secret the secret
|
||||
*
|
||||
* @return string original data
|
||||
* @return string|bool original data, false on error
|
||||
*/
|
||||
public function blowfishDecrypt($encdata, $secret)
|
||||
public function cookieDecrypt($encdata, $secret)
|
||||
{
|
||||
global $iv;
|
||||
$data = json_decode($encdata, true);
|
||||
|
||||
if (! is_array($data) || ! isset($data['mac']) || ! isset($data['iv']) || ! isset($data['payload'])
|
||||
|| ! is_string($data['mac']) || ! is_string($data['iv']) || ! is_string($data['payload'])
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$mac_secret = $this->getMACSecret($secret);
|
||||
$aes_secret = $this->getAESSecret($secret);
|
||||
$newmac = hash_hmac('sha1', $data['iv'] . $data['payload'], $mac_secret);
|
||||
|
||||
if (! hash_equals($data['mac'], $newmac)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! function_exists('mcrypt_encrypt')) {
|
||||
include_once "./libraries/phpseclib/Crypt/AES.php";
|
||||
$cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
|
||||
$cipher->setKey($secret);
|
||||
return $cipher->decrypt(base64_decode($encdata));
|
||||
$cipher->setIV(base64_decode($data['iv']));
|
||||
$cipher->setKey($aes_secret);
|
||||
return $cipher->decrypt(base64_decode($data['payload']));
|
||||
} else {
|
||||
$data = base64_decode($encdata);
|
||||
$decrypted = mcrypt_decrypt(
|
||||
MCRYPT_BLOWFISH,
|
||||
$secret,
|
||||
$data,
|
||||
base64_decode($data['payload']),
|
||||
MCRYPT_MODE_CBC,
|
||||
$iv
|
||||
base64_decode($data['iv'])
|
||||
);
|
||||
return trim($decrypted);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns size of IV for encryption.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getIVSize()
|
||||
{
|
||||
include_once "./libraries/phpseclib/Crypt/AES.php";
|
||||
$cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
|
||||
return $cipher->block_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization
|
||||
* Store the initialization vector because it will be needed for
|
||||
* further decryption. I don't think necessary to have one iv
|
||||
* per server so I don't put the server number in the cookie name.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function createIV()
|
||||
{
|
||||
if (function_exists('mcrypt_create_iv')) {
|
||||
srand((double) microtime() * 1000000);
|
||||
$td = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_CBC, '');
|
||||
if ($td === false) {
|
||||
PMA_fatalError(__('Failed to use Blowfish from mcrypt!'));
|
||||
}
|
||||
return mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
|
||||
} else {
|
||||
include_once "./libraries/phpseclib/Crypt/Random.php";
|
||||
return crypt_random_string(
|
||||
$this->getIVSize()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when any PluginManager to which the observer
|
||||
* is attached calls PluginManager::notify()
|
||||
|
||||
@ -158,10 +158,13 @@ class AuthenticationHttp extends AuthenticationPlugin
|
||||
unset($usr_pass);
|
||||
}
|
||||
|
||||
// sanitize username
|
||||
$PHP_AUTH_USER = PMA_sanitizeMySQLUser($PHP_AUTH_USER);
|
||||
|
||||
// User logged out -> ensure the new username is not the same
|
||||
$old_usr = isset($_REQUEST['old_usr']) ? $_REQUEST['old_usr'] : '';
|
||||
if (! empty($old_usr)
|
||||
&& (isset($PHP_AUTH_USER) && $old_usr == $PHP_AUTH_USER)
|
||||
&& (isset($PHP_AUTH_USER) && hash_equals($old_usr, $PHP_AUTH_USER))
|
||||
) {
|
||||
$PHP_AUTH_USER = '';
|
||||
// -> delete user's choices that were stored in session
|
||||
@ -194,12 +197,12 @@ class AuthenticationHttp extends AuthenticationPlugin
|
||||
|
||||
// Ensures valid authentication mode, 'only_db', bookmark database and
|
||||
// table names and relation table name are used
|
||||
if ($cfg['Server']['user'] != $PHP_AUTH_USER) {
|
||||
if (! hash_equals($cfg['Server']['user'], $PHP_AUTH_USER)) {
|
||||
$servers_cnt = count($cfg['Servers']);
|
||||
for ($i = 1; $i <= $servers_cnt; $i++) {
|
||||
if (isset($cfg['Servers'][$i])
|
||||
&& ($cfg['Servers'][$i]['host'] == $cfg['Server']['host']
|
||||
&& $cfg['Servers'][$i]['user'] == $PHP_AUTH_USER)
|
||||
&& hash_equals($cfg['Servers'][$i]['user'], $PHP_AUTH_USER))
|
||||
) {
|
||||
$server = $i;
|
||||
$cfg['Server'] = $cfg['Servers'][$i];
|
||||
|
||||
@ -1,172 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Swekey
|
||||
*/
|
||||
?>
|
||||
|
||||
<script>
|
||||
|
||||
var g_SwekeyPlugin = null;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Create the swekey plugin if it does not exists
|
||||
function Swekey_Plugin()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (g_SwekeyPlugin != null)
|
||||
return g_SwekeyPlugin;
|
||||
|
||||
if (window.ActiveXObject)
|
||||
{
|
||||
g_SwekeyPlugin = document.getElementById("swekey_activex");
|
||||
if (g_SwekeyPlugin == null)
|
||||
{
|
||||
// we must create the activex that way instead of new ActiveXObject("FbAuthAx.FbAuthCtl");
|
||||
// ortherwise SetClientSite is not called and we can not get the url
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML='<object id="swekey_activex" style="display:none" CLASSID="CLSID:8E02E3F9-57AA-4EE1-AA68-A42DD7B0FADE"></object>';
|
||||
|
||||
// Never append to the body because it may still loading and it breaks IE
|
||||
document.body.insertBefore(div, document.body.firstChild);
|
||||
g_SwekeyPlugin = document.getElementById("swekey_activex");
|
||||
}
|
||||
return g_SwekeyPlugin;
|
||||
}
|
||||
|
||||
g_SwekeyPlugin = document.getElementById("swekey_plugin");
|
||||
if (g_SwekeyPlugin != null)
|
||||
return g_SwekeyPlugin;
|
||||
|
||||
for (i = 0; i < navigator.plugins.length; i ++)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (navigator.plugins[i] == null)
|
||||
{
|
||||
navigator.plugins.refresh();
|
||||
}
|
||||
else if (navigator.plugins[i][0] != null && navigator.plugins[i][0].type == "application/fbauth-plugin")
|
||||
{
|
||||
var x = document.createElement('embed');
|
||||
x.setAttribute('type', 'application/fbauth-plugin');
|
||||
x.setAttribute('id', 'swekey_plugin');
|
||||
x.setAttribute('width', '0');
|
||||
x.setAttribute('height', '0');
|
||||
x.style.dislay='none';
|
||||
|
||||
//document.body.appendChild(x);
|
||||
document.body.insertBefore(x, document.body.firstChild);
|
||||
g_SwekeyPlugin = document.getElementById("swekey_plugin");
|
||||
return g_SwekeyPlugin;
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
navigator.plugins.refresh();
|
||||
//alert ('Failed to create plugin: ' + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
//alert("Swekey_Plugin " + e);
|
||||
g_SwekeyPlugin = null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Returns true if the swekey plugin is installed
|
||||
function Swekey_Installed()
|
||||
{
|
||||
return (Swekey_Plugin() != null);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// List the id of the Swekey connected to the PC
|
||||
// Returns a string containing comma separated Swekey Ids
|
||||
// A Swekey is a 32 char hexadecimal value.
|
||||
function Swekey_ListKeyIds()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Swekey_Plugin().list();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
// alert("Swekey_ListKeyIds " + e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Ask the Connected Swekey to generate an OTP
|
||||
// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
|
||||
// rt: A random token
|
||||
// return: The calculated OTP encoded in a 64 chars hexadecimal value.
|
||||
function Swekey_GetOtp(id, rt)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Swekey_Plugin().getotp(id, rt);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
// alert("Swekey_GetOtp " + e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Ask the Connected Swekey to generate a OTP linked to the current https host
|
||||
// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
|
||||
// rt: A random token
|
||||
// return: The calculated OTP encoded in a 64 chars hexadecimal value.
|
||||
// or "" if the current url does not start with https
|
||||
function Swekey_GetLinkedOtp(id, rt)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Swekey_Plugin().getlinkedotp(id, rt);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
// alert("Swekey_GetSOtp " + e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Calls Swekey_GetOtp or Swekey_GetLinkedOtp depending if we are in
|
||||
// an https page or not.
|
||||
// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
|
||||
// rt: A random token
|
||||
// return: The calculated OTP encoded in a 64 chars hexadecimal value.
|
||||
function Swekey_GetSmartOtp(id, rt)
|
||||
{
|
||||
var res = Swekey_GetLinkedOtp(id, rt);
|
||||
if (res == "")
|
||||
res = Swekey_GetOtp(id, rt);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Set a unplug handler (url) to the specified connected feebee
|
||||
// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
|
||||
// key: The key that index that url, (aplhanumeric values only)
|
||||
// url: The url that will be launched ("" deletes the url)
|
||||
function Swekey_SetUnplugUrl(id, key, url)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Swekey_Plugin().setunplugurl(id, key, url);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
// alert("Swekey_SetUnplugUrl " + e);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
@ -1,25 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEKjCCAxKgAwIBAgIJAMjw7QcLWCd6MA0GCSqGSIb3DQEBBQUAMGsxCzAJBgNV
|
||||
BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQKEwtNdXNiZSwgSW5j
|
||||
LjESMBAGA1UEAxMJbXVzYmUuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQG11c2Jl
|
||||
LmNvbTAeFw0wODA5MDQxNDE2MTNaFw0zNzEyMjExNDE2MTNaMGsxCzAJBgNVBAYT
|
||||
AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQKEwtNdXNiZSwgSW5jLjES
|
||||
MBAGA1UEAxMJbXVzYmUuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQG11c2JlLmNv
|
||||
bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOBhOljxVzQfK4gted2I
|
||||
d3BemcjW4abAUOzn3KYWXpPO5xIfVeXNDGkDbyH+X+7fo94sX25/ewuKNFDSOcvo
|
||||
tXHq7uQenTHB35r+a+LY81KceUHgW90a3XsqPAkwAjyYcgo3zmM2DtLvw+5Yod8T
|
||||
wAHk9m3qavnQ1uk99jBTwL7RZ9jIZHh9pFCL93uJc2obtd8O96Iycbn2q0w/AWbb
|
||||
+eUVWIHzvLtfPvROeL3lJzr/Uz5LjKapxJ3qyqASflfHpnj9pU8l6g2TQ6Hg5KT5
|
||||
tLFkRe7uGhOfRtOQ/+NjaWrEuNCFnpyN4Q5Fv+5qA1Ip1IpH0200sWbAf/k2u0Qp
|
||||
Sx0CAwEAAaOB0DCBzTAdBgNVHQ4EFgQUczJrQ7hCvtsnzcqiDIZ/GSn/CiwwgZ0G
|
||||
A1UdIwSBlTCBkoAUczJrQ7hCvtsnzcqiDIZ/GSn/Ciyhb6RtMGsxCzAJBgNVBAYT
|
||||
AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQKEwtNdXNiZSwgSW5jLjES
|
||||
MBAGA1UEAxMJbXVzYmUuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQG11c2JlLmNv
|
||||
bYIJAMjw7QcLWCd6MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAGxk
|
||||
8xzIljeBDQWWVRr0NEALVSv3i09V4jAKkyEOfmZ8lKMKJi0atwbtjrXTzLnNYj+Q
|
||||
pyUbyY/8ItWvV7pnVxMiF9qcer7e9X4vw358GZuMVE/da1nWxz+CwzTm5oO30RzA
|
||||
antM9bISFFr9lJq69bDWOnCUi1IG8DSL3TxtlABso7S4vqiZ+sB33l6k1K4a/Njb
|
||||
QkU9UejKhKkVVZTsOrumfnOJ4MCmPfX8Y/AY2o670y5HnzpxerIYziCVzApPVrW7
|
||||
sKH0tuVGturMfQOKgstYe4/m9glBTeTLMkjD+6MJC2ONBD7GAiOO95gNl5M1fzJQ
|
||||
FEe5CJ7DCYl0GdmLXXw=
|
||||
-----END CERTIFICATE-----
|
||||
@ -1,297 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Swekey
|
||||
*/
|
||||
|
||||
if (! defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks Swekey authentication.
|
||||
*/
|
||||
function Swekey_auth_check()
|
||||
{
|
||||
global $cfg;
|
||||
$confFile = $cfg['Server']['auth_swekey_config'];
|
||||
|
||||
if (! isset($_SESSION['SWEKEY'])) {
|
||||
$_SESSION['SWEKEY'] = array();
|
||||
}
|
||||
|
||||
$_SESSION['SWEKEY']['ENABLED'] = (! empty($confFile) && file_exists($confFile));
|
||||
|
||||
// Load the swekey.conf file the first time
|
||||
if ($_SESSION['SWEKEY']['ENABLED']
|
||||
&& empty($_SESSION['SWEKEY']['CONF_LOADED'])
|
||||
) {
|
||||
$_SESSION['SWEKEY']['CONF_LOADED'] = true;
|
||||
$_SESSION['SWEKEY']['VALID_SWEKEYS'] = array();
|
||||
$valid_swekeys = explode("\n", @file_get_contents($confFile));
|
||||
foreach ($valid_swekeys as $line) {
|
||||
if (preg_match("/^[0-9A-F]{32}:.+$/", $line) != false) {
|
||||
$items = explode(":", $line);
|
||||
if (count($items) == 2) {
|
||||
$_SESSION['SWEKEY']['VALID_SWEKEYS'][$items[0]] = trim($items[1]);
|
||||
}
|
||||
} elseif (preg_match("/^[A-Z_]+=.*$/", $line) != false) {
|
||||
$items = explode("=", $line);
|
||||
$_SESSION['SWEKEY']['CONF_'.trim($items[0])] = trim($items[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// Set default values for settings
|
||||
if (! isset($_SESSION['SWEKEY']['CONF_SERVER_CHECK'])) {
|
||||
$_SESSION['SWEKEY']['CONF_SERVER_CHECK'] = "";
|
||||
}
|
||||
if (! isset($_SESSION['SWEKEY']['CONF_SERVER_RNDTOKEN'])) {
|
||||
$_SESSION['SWEKEY']['CONF_SERVER_RNDTOKEN'] = "";
|
||||
}
|
||||
if (! isset($_SESSION['SWEKEY']['CONF_SERVER_STATUS'])) {
|
||||
$_SESSION['SWEKEY']['CONF_SERVER_STATUS'] = "";
|
||||
}
|
||||
if (! isset($_SESSION['SWEKEY']['CONF_CA_FILE'])) {
|
||||
$_SESSION['SWEKEY']['CONF_CA_FILE'] = "";
|
||||
}
|
||||
if (! isset($_SESSION['SWEKEY']['CONF_ENABLE_TOKEN_CACHE'])) {
|
||||
$_SESSION['SWEKEY']['CONF_ENABLE_TOKEN_CACHE'] = true;
|
||||
}
|
||||
if (! isset($_SESSION['SWEKEY']['CONF_DEBUG'])) {
|
||||
$_SESSION['SWEKEY']['CONF_DEBUG'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
// check if a web key has been authenticated
|
||||
if ($_SESSION['SWEKEY']['ENABLED']) {
|
||||
if (empty($_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY'])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle Swekey authentication error.
|
||||
*/
|
||||
function Swekey_auth_error()
|
||||
{
|
||||
if (! isset($_SESSION['SWEKEY'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $_SESSION['SWEKEY']['ENABLED']) {
|
||||
return null;
|
||||
}
|
||||
|
||||
include_once './libraries/plugins/auth/swekey/authentication.inc.php';
|
||||
|
||||
?>
|
||||
<script>
|
||||
function Swekey_GetValidKey()
|
||||
{
|
||||
var valids = "<?php
|
||||
foreach ($_SESSION['SWEKEY']['VALID_SWEKEYS'] as $key => $value) {
|
||||
echo $key.',';
|
||||
}
|
||||
?>";
|
||||
var connected_keys = Swekey_ListKeyIds().split(",");
|
||||
for (i in connected_keys) {
|
||||
if (connected_keys[i] != null && connected_keys[i].length == 32) {
|
||||
if (valids.indexOf(connected_keys[i]) >= 0) {
|
||||
return connected_keys[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (connected_keys.length > 0) {
|
||||
if (connected_keys[0].length == 32) {
|
||||
return "unknown_key_" + connected_keys[0];
|
||||
}
|
||||
}
|
||||
|
||||
return "none";
|
||||
}
|
||||
|
||||
var key = Swekey_GetValidKey();
|
||||
|
||||
function timedCheck()
|
||||
{
|
||||
if (key != Swekey_GetValidKey()) {
|
||||
window.location.search = "?swekey_reset";
|
||||
} else {
|
||||
setTimeout("timedCheck()",1000);
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout("timedCheck()",1000);
|
||||
</script>
|
||||
<?php
|
||||
|
||||
if (! empty($_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (count($_SESSION['SWEKEY']['VALID_SWEKEYS']) == 0) {
|
||||
return sprintf(__('File %s does not contain any key id'), $GLOBALS['cfg']['Server']['auth_swekey_config']);
|
||||
}
|
||||
|
||||
include_once "libraries/plugins/auth/swekey/swekey.php";
|
||||
|
||||
Swekey_SetCheckServer($_SESSION['SWEKEY']['CONF_SERVER_CHECK']);
|
||||
Swekey_SetRndTokenServer($_SESSION['SWEKEY']['CONF_SERVER_RNDTOKEN']);
|
||||
Swekey_SetStatusServer($_SESSION['SWEKEY']['CONF_SERVER_STATUS']);
|
||||
Swekey_EnableTokenCache($_SESSION['SWEKEY']['CONF_ENABLE_TOKEN_CACHE']);
|
||||
|
||||
$caFile = $_SESSION['SWEKEY']['CONF_CA_FILE'];
|
||||
if (empty($caFile)) {
|
||||
$caFile = __FILE__;
|
||||
$pos = strrpos($caFile, '/');
|
||||
if ($pos === false) {
|
||||
$pos = strrpos($caFile, '\\'); // windows
|
||||
}
|
||||
$caFile = substr($caFile, 0, $pos + 1).'musbe-ca.crt';
|
||||
// echo "\n<!-- $caFile -->\n";
|
||||
// if (file_exists($caFile))
|
||||
// echo "<!-- exists -->\n";
|
||||
}
|
||||
|
||||
if (file_exists($caFile)) {
|
||||
Swekey_SetCAFile($caFile);
|
||||
} elseif (! empty($caFile) && (substr($_SESSION['SWEKEY']['CONF_SERVER_CHECK'], 0, 8) == "https://")) {
|
||||
return "Internal Error: CA File $caFile not found";
|
||||
}
|
||||
|
||||
$result = null;
|
||||
$swekey_id = $_GET['swekey_id'];
|
||||
$swekey_otp = $_GET['swekey_otp'];
|
||||
|
||||
if (isset($swekey_id)) {
|
||||
unset($_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY']);
|
||||
if (! isset($_SESSION['SWEKEY']['RND_TOKEN'])) {
|
||||
unset($swekey_id);
|
||||
} else {
|
||||
if (strlen($swekey_id) == 32) {
|
||||
$res = Swekey_CheckOtp($swekey_id, $_SESSION['SWEKEY']['RND_TOKEN'], $swekey_otp);
|
||||
unset($_SESSION['SWEKEY']['RND_TOKEN']);
|
||||
if (! $res) {
|
||||
$result = __('Hardware authentication failed') . ' (' . Swekey_GetLastError() . ')';
|
||||
} else {
|
||||
$_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY'] = $swekey_id;
|
||||
$_SESSION['SWEKEY']['FORCE_USER'] = $_SESSION['SWEKEY']['VALID_SWEKEYS'][$swekey_id];
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
$result = __('No valid authentication key plugged');
|
||||
if ($_SESSION['SWEKEY']['CONF_DEBUG']) {
|
||||
$result .= "<br/>" . htmlspecialchars($swekey_id);
|
||||
}
|
||||
unset($_SESSION['SWEKEY']['CONF_LOADED']); // reload the conf file
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unset($_SESSION['SWEKEY']);
|
||||
}
|
||||
|
||||
$_SESSION['SWEKEY']['RND_TOKEN'] = Swekey_GetFastRndToken();
|
||||
if (strlen($_SESSION['SWEKEY']['RND_TOKEN']) != 64) {
|
||||
$result = __('Hardware authentication failed') . ' (' . Swekey_GetLastError() . ')';
|
||||
unset($_SESSION['SWEKEY']['CONF_LOADED']); // reload the conf file
|
||||
}
|
||||
|
||||
if (! isset($swekey_id)) {
|
||||
?>
|
||||
<script>
|
||||
if (key.length != 32) {
|
||||
window.location.search="?swekey_id=" + key + "&token=<?php echo $_SESSION[' PMA_token ']; ?>";
|
||||
} else {
|
||||
var url = "" + window.location;
|
||||
if (url.indexOf("?") > 0) {
|
||||
url = url.substr(0, url.indexOf("?"));
|
||||
}
|
||||
Swekey_SetUnplugUrl(key, "pma_login", url + "?session_to_unset=<?php echo session_id();?>&token=<?php echo $_SESSION[' PMA_token ']; ?>");
|
||||
var otp = Swekey_GetOtp(key, <?php echo '"'.$_SESSION['SWEKEY']['RND_TOKEN'].'"';?>);
|
||||
window.location.search="?swekey_id=" + key + "&swekey_otp=" + otp + "&token=<?php echo $_SESSION[' PMA_token ']; ?>";
|
||||
}
|
||||
</script>
|
||||
<?php
|
||||
return __('Authenticating…');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform login using Swekey.
|
||||
*/
|
||||
function Swekey_login($input_name, $input_go)
|
||||
{
|
||||
$swekeyErr = Swekey_auth_error();
|
||||
if ($swekeyErr != null) {
|
||||
PMA_Message::error($swekeyErr)->display();
|
||||
if ($GLOBALS['error_handler']->hasDisplayErrors()) {
|
||||
echo '<div>';
|
||||
$GLOBALS['error_handler']->dispErrors();
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_SESSION['SWEKEY']) && $_SESSION['SWEKEY']['ENABLED']) {
|
||||
echo '<script type="text/javascript">';
|
||||
if (empty($_SESSION['SWEKEY']['FORCE_USER'])) {
|
||||
echo 'var user = null;';
|
||||
} else {
|
||||
echo 'var user = "'.$_SESSION['SWEKEY']['FORCE_USER'].'";';
|
||||
}
|
||||
|
||||
?>
|
||||
function open_swekey_site()
|
||||
{
|
||||
window.open("<?php echo PMA_linkURL('http://phpmyadmin.net/auth_key'); ?>");
|
||||
}
|
||||
|
||||
var input_username = document.getElementById("<?php echo $input_name; ?>");
|
||||
var input_go = document.getElementById("<?php echo $input_go; ?>");
|
||||
var swekey_status = document.createElement('img');
|
||||
swekey_status.setAttribute('onclick', 'open_swekey_site()');
|
||||
swekey_status.setAttribute('style', 'width:8px; height:16px; border:0px; vspace:0px; hspace:0px; frameborder:no');
|
||||
if (user == null) {
|
||||
swekey_status.setAttribute('src', 'http://artwork.swekey.com/unplugged-8x16.png');
|
||||
//swekey_status.setAttribute('title', 'No swekey plugged');
|
||||
input_go.disabled = true;
|
||||
} else {
|
||||
swekey_status.setAttribute('src', 'http://artwork.swekey.com/plugged-8x16.png');
|
||||
//swekey_status.setAttribute('title', 'swekey plugged');
|
||||
input_username.value = user;
|
||||
}
|
||||
input_username.readOnly = true;
|
||||
|
||||
if (input_username.nextSibling == null) {
|
||||
input_username.parentNode.appendChild(swekey_status);
|
||||
} else {
|
||||
input_username.parentNode.insertBefore(swekey_status, input_username.nextSibling);
|
||||
}
|
||||
|
||||
<?php
|
||||
echo '</script>';
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_GET['session_to_unset'])) {
|
||||
session_write_close();
|
||||
session_id($_GET['session_to_unset']);
|
||||
session_start();
|
||||
$_SESSION = array();
|
||||
session_write_close();
|
||||
session_destroy();
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_GET['swekey_reset'])) {
|
||||
unset($_SESSION['SWEKEY']);
|
||||
}
|
||||
|
||||
?>
|
||||
@ -1,522 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Library that provides common functions that are used to help integrating Swekey Authentication in a PHP web site
|
||||
* Version 1.0
|
||||
*
|
||||
* History:
|
||||
* 1.2 Use curl (widely installed) to query the server
|
||||
* Fixed a possible tempfile race attack
|
||||
* Random token cache can now be disabled
|
||||
* 1.1 Added Swekey_HttpGet function that support faulty servers
|
||||
* Support for custom servers
|
||||
* 1.0 First release
|
||||
*
|
||||
* @package Swekey
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Errors codes
|
||||
*/
|
||||
define("SWEKEY_ERR_INVALID_DEV_STATUS", 901); // The satus of the device is not SWEKEY_STATUS_OK
|
||||
define("SWEKEY_ERR_INTERNAL", 902); // Should never occurd
|
||||
define("SWEKEY_ERR_OUTDATED_RND_TOKEN", 910); // You random token is too old
|
||||
define("SWEKEY_ERR_INVALID_OTP", 911); // The otp was not correct
|
||||
|
||||
/**
|
||||
* Those errors are considered as an attack and your site will be blacklisted during one minute
|
||||
* if you receive one of those errors
|
||||
*/
|
||||
define("SWEKEY_ERR_BADLY_ENCODED_REQUEST", 920);
|
||||
define("SWEKEY_ERR_INVALID_RND_TOKEN", 921);
|
||||
define("SWEKEY_ERR_DEV_NOT_FOUND", 922);
|
||||
|
||||
/**
|
||||
* Default values for configuration.
|
||||
*/
|
||||
define('SWEKEY_DEFAULT_CHECK_SERVER', 'https://auth-check.musbe.net');
|
||||
define('SWEKEY_DEFAULT_RND_SERVER', 'https://auth-rnd-gen.musbe.net');
|
||||
define('SWEKEY_DEFAULT_STATUS_SERVER', 'https://auth-status.musbe.net');
|
||||
|
||||
/**
|
||||
* The last error of an operation is alway put in this global var
|
||||
*/
|
||||
|
||||
global $gSwekeyLastError;
|
||||
$gSwekeyLastError = 0;
|
||||
|
||||
global $gSwekeyLastResult;
|
||||
$gSwekeyLastResult = "<not set>";
|
||||
|
||||
/**
|
||||
* Servers addresses
|
||||
* Use the Swekey_SetXxxServer($server) functions to set them
|
||||
*/
|
||||
|
||||
global $gSwekeyCheckServer;
|
||||
if (! isset($gSwekeyCheckServer)) {
|
||||
$gSwekeyCheckServer = SWEKEY_DEFAULT_CHECK_SERVER;
|
||||
}
|
||||
|
||||
global $gSwekeyRndTokenServer;
|
||||
if (! isset($gSwekeyRndTokenServer)) {
|
||||
$gSwekeyRndTokenServer = SWEKEY_DEFAULT_RND_SERVER;
|
||||
}
|
||||
|
||||
global $gSwekeyStatusServer;
|
||||
if (! isset($gSwekeyStatusServer)) {
|
||||
$gSwekeyStatusServer = SWEKEY_DEFAULT_STATUS_SERVER;
|
||||
}
|
||||
|
||||
global $gSwekeyCA;
|
||||
|
||||
global $gSwekeyTokenCacheEnabled;
|
||||
if (! isset($gSwekeyTokenCacheEnabled)) {
|
||||
$gSwekeyTokenCacheEnabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the address of the Check server.
|
||||
* If $server is empty the default value 'http://auth-check.musbe.net' will be used
|
||||
*
|
||||
* @param server The protocol and hostname to use
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function Swekey_SetCheckServer($server)
|
||||
{
|
||||
global $gSwekeyCheckServer;
|
||||
if (empty($server)) {
|
||||
$gSwekeyCheckServer = SWEKEY_DEFAULT_CHECK_SERVER;
|
||||
} else {
|
||||
$gSwekeyCheckServer = $server;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the address of the Random Token Generator server.
|
||||
* If $server is empty the default value 'http://auth-rnd-gen.musbe.net' will be used
|
||||
*
|
||||
* @param server The protocol and hostname to use
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function Swekey_SetRndTokenServer($server)
|
||||
{
|
||||
global $gSwekeyRndTokenServer;
|
||||
if (empty($server)) {
|
||||
$gSwekeyRndTokenServer = SWEKEY_DEFAULT_RND_SERVER;
|
||||
} else {
|
||||
$gSwekeyRndTokenServer = $server;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the address of the Satus server.
|
||||
* If $server is empty the default value 'http://auth-status.musbe.net' will be used
|
||||
*
|
||||
* @param server The protocol and hostname to use
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function Swekey_SetStatusServer($server)
|
||||
{
|
||||
global $gSwekeyStatusServer;
|
||||
if (empty($server)) {
|
||||
$gSwekeyStatusServer = SWEKEY_DEFAULT_STATUS_SERVER;
|
||||
} else {
|
||||
$gSwekeyStatusServer = $server;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the certificat file in case of the the severs use https instead of http
|
||||
*
|
||||
* @param cafile The path of the crt file to use
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function Swekey_SetCAFile($cafile)
|
||||
{
|
||||
global $gSwekeyCA;
|
||||
$gSwekeyCA = $cafile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable the random token caching
|
||||
* Because everybody has full access to the cache file, it can be a DOS vulnerability
|
||||
* So disable it if you are running in a non secure enviromnement
|
||||
*
|
||||
* @param $enable
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function Swekey_EnableTokenCache($enable)
|
||||
{
|
||||
global $gSwekeyTokenCacheEnabled;
|
||||
$gSwekeyTokenCacheEnabled = ! empty($enable);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the last error.
|
||||
*
|
||||
* @return The Last Error
|
||||
* @access public
|
||||
*/
|
||||
function Swekey_GetLastError()
|
||||
{
|
||||
global $gSwekeyLastError;
|
||||
return $gSwekeyLastError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the last result.
|
||||
*
|
||||
* @return The Last Error
|
||||
* @access public
|
||||
*/
|
||||
function Swekey_GetLastResult()
|
||||
{
|
||||
global $gSwekeyLastResult;
|
||||
return $gSwekeyLastResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a synchronous request to the server.
|
||||
* This function manages timeout then will not block if one of the server is down
|
||||
*
|
||||
* @param url The url to get
|
||||
* @param response_code The response code
|
||||
*
|
||||
* @return The body of the response or "" in case of error
|
||||
* @access private
|
||||
*/
|
||||
function Swekey_HttpGet($url, &$response_code)
|
||||
{
|
||||
global $gSwekeyLastError;
|
||||
$gSwekeyLastError = 0;
|
||||
global $gSwekeyLastResult;
|
||||
$gSwekeyLastResult = "<not set>";
|
||||
|
||||
// use curl if available
|
||||
if (function_exists('curl_init')) {
|
||||
$sess = curl_init($url);
|
||||
if (substr($url, 0, 8) == "https://") {
|
||||
global $gSwekeyCA;
|
||||
|
||||
if (! empty($gSwekeyCA)) {
|
||||
if (file_exists($gSwekeyCA)) {
|
||||
if (! curl_setopt($sess, CURLOPT_CAINFO, $gSwekeyCA)) {
|
||||
error_log("SWEKEY_ERROR:Could not set CA file : ".curl_error($sess));
|
||||
} else {
|
||||
$caFileOk = true;
|
||||
}
|
||||
} else {
|
||||
error_log("SWEKEY_ERROR:Could not find CA file $gSwekeyCA getting $url");
|
||||
}
|
||||
}
|
||||
|
||||
curl_setopt($sess, CURLOPT_SSL_VERIFYHOST, '2');
|
||||
curl_setopt($sess, CURLOPT_SSL_VERIFYPEER, '2');
|
||||
curl_setopt($sess, CURLOPT_CONNECTTIMEOUT, '20');
|
||||
curl_setopt($sess, CURLOPT_TIMEOUT, '20');
|
||||
} else {
|
||||
curl_setopt($sess, CURLOPT_CONNECTTIMEOUT, '3');
|
||||
curl_setopt($sess, CURLOPT_TIMEOUT, '5');
|
||||
}
|
||||
|
||||
curl_setopt($sess, CURLOPT_RETURNTRANSFER, '1');
|
||||
$res=curl_exec($sess);
|
||||
$response_code = curl_getinfo($sess, CURLINFO_HTTP_CODE);
|
||||
$curlerr = curl_error($sess);
|
||||
curl_close($sess);
|
||||
|
||||
if ($response_code == 200) {
|
||||
$gSwekeyLastResult = $res;
|
||||
return $res;
|
||||
}
|
||||
|
||||
if (! empty($response_code)) {
|
||||
$gSwekeyLastError = $response_code;
|
||||
error_log("SWEKEY_ERROR:Error $gSwekeyLastError ($curlerr) getting $url");
|
||||
return "";
|
||||
}
|
||||
|
||||
$response_code = 408; // Request Timeout
|
||||
$gSwekeyLastError = $response_code;
|
||||
error_log("SWEKEY_ERROR:Error $curlerr getting $url");
|
||||
return "";
|
||||
}
|
||||
|
||||
// use pecl_http if available
|
||||
if (class_exists('HttpRequest')) {
|
||||
// retry if one of the server is down
|
||||
for ($num=1; $num <= 3; $num++ ) {
|
||||
$r = new HttpRequest($url);
|
||||
$options = array('timeout' => '3');
|
||||
|
||||
if (substr($url, 0, 6) == "https:") {
|
||||
$sslOptions = array();
|
||||
$sslOptions['verifypeer'] = true;
|
||||
$sslOptions['verifyhost'] = true;
|
||||
|
||||
$capath = __FILE__;
|
||||
$name = strrchr($capath, '/');
|
||||
// windows
|
||||
if (empty($name)) {
|
||||
$name = strrchr($capath, '\\');
|
||||
}
|
||||
$capath = substr($capath, 0, strlen($capath) - strlen($name) + 1).'musbe-ca.crt';
|
||||
|
||||
if (! empty($gSwekeyCA)) {
|
||||
$sslOptions['cainfo'] = $gSwekeyCA;
|
||||
}
|
||||
|
||||
$options['ssl'] = $sslOptions;
|
||||
}
|
||||
|
||||
$r->setOptions($options);
|
||||
|
||||
// try
|
||||
{
|
||||
$reply = $r->send();
|
||||
$res = $reply->getBody();
|
||||
$info = $r->getResponseInfo();
|
||||
$response_code = $info['response_code'];
|
||||
if ($response_code != 200) {
|
||||
$gSwekeyLastError = $response_code;
|
||||
error_log("SWEKEY_ERROR:Error ".$gSwekeyLastError." getting ".$url);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
$gSwekeyLastResult = $res;
|
||||
return $res;
|
||||
}
|
||||
// catch (HttpException $e)
|
||||
// {
|
||||
// error_log("SWEKEY_WARNING:HttpException ".$e." getting ".$url);
|
||||
// }
|
||||
}
|
||||
|
||||
$response_code = 408; // Request Timeout
|
||||
$gSwekeyLastError = $response_code;
|
||||
error_log("SWEKEY_ERROR:Error ".$gSwekeyLastError." getting ".$url);
|
||||
return "";
|
||||
}
|
||||
|
||||
global $http_response_header;
|
||||
$res = @file_get_contents($url);
|
||||
$response_code = substr($http_response_header[0], 9, 3); //HTTP/1.0
|
||||
if ($response_code == 200) {
|
||||
$gSwekeyLastResult = $res;
|
||||
return $res;
|
||||
}
|
||||
|
||||
$gSwekeyLastError = $response_code;
|
||||
error_log("SWEKEY_ERROR:Error ".$response_code." getting ".$url);
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Random Token from a Token Server
|
||||
* The RT is a 64 vhars hexadecimal value
|
||||
* You should better use Swekey_GetFastRndToken() for performance
|
||||
* @access public
|
||||
*/
|
||||
function Swekey_GetRndToken()
|
||||
{
|
||||
global $gSwekeyRndTokenServer;
|
||||
return Swekey_HttpGet($gSwekeyRndTokenServer.'/FULL-RND-TOKEN', $response_code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Half Random Token from a Token Server
|
||||
* The RT is a 64 vhars hexadecimal value
|
||||
* Use this value if you want to make your own Swekey_GetFastRndToken()
|
||||
* @access public
|
||||
*/
|
||||
function Swekey_GetHalfRndToken()
|
||||
{
|
||||
global $gSwekeyRndTokenServer;
|
||||
return Swekey_HttpGet($gSwekeyRndTokenServer.'/HALF-RND-TOKEN', $response_code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Half Random Token
|
||||
* The RT is a 64 vhars hexadecimal value
|
||||
* This function get a new random token and reuse it.
|
||||
* Token are refetched from the server only once every 30 seconds.
|
||||
* You should always use this function to get half random token.
|
||||
* @access public
|
||||
*/
|
||||
function Swekey_GetFastHalfRndToken()
|
||||
{
|
||||
global $gSwekeyTokenCacheEnabled;
|
||||
|
||||
$res = "";
|
||||
$cachefile = "";
|
||||
|
||||
// We check if we have a valid RT is the session
|
||||
if (isset($_SESSION['rnd-token-date'])) {
|
||||
if (time() - $_SESSION['rnd-token-date'] < 30) {
|
||||
$res = $_SESSION['rnd-token'];
|
||||
}
|
||||
}
|
||||
|
||||
// If not we try to get it from a temp file (PHP >= 5.2.1 only)
|
||||
if (strlen($res) != 32 && $gSwekeyTokenCacheEnabled) {
|
||||
if (function_exists('sys_get_temp_dir')) {
|
||||
$tempdir = sys_get_temp_dir();
|
||||
$cachefile = $tempdir."/swekey-rnd-token-".get_current_user();
|
||||
$modif = filemtime($cachefile);
|
||||
if ($modif != false) {
|
||||
if (time() - $modif < 30) {
|
||||
$res = @file_get_contents($cachefile);
|
||||
if (strlen($res) != 32) {
|
||||
$res = "";
|
||||
} else {
|
||||
$_SESSION['rnd-token'] = $res;
|
||||
$_SESSION['rnd-token-date'] = $modif;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we don't have a valid RT here we have to get it from the server
|
||||
if (strlen($res) != 32) {
|
||||
$res = substr(Swekey_GetHalfRndToken(), 0, 32);
|
||||
$_SESSION['rnd-token'] = $res;
|
||||
$_SESSION['rnd-token-date'] = time();
|
||||
if (! empty($cachefile)) {
|
||||
// we unlink the file so no possible tempfile race attack
|
||||
unlink($cachefile);
|
||||
$file = fopen($cachefile, "x");
|
||||
if ($file != false) {
|
||||
@fwrite($file, $res);
|
||||
@fclose($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $res."00000000000000000000000000000000";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Random Token
|
||||
* The RT is a 64 vhars hexadecimal value
|
||||
* This function generates a unique random token for each call but call the
|
||||
* server only once every 30 seconds.
|
||||
* You should always use this function to get random token.
|
||||
* @access public
|
||||
*/
|
||||
function Swekey_GetFastRndToken()
|
||||
{
|
||||
$res = Swekey_GetFastHalfRndToken();
|
||||
if (strlen($res) == 64) {
|
||||
return substr($res, 0, 32).strtoupper(md5("Musbe Authentication Key" . mt_rand() . date(DATE_ATOM)));
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks that an OTP generated by a Swekey is valid
|
||||
*
|
||||
* @param id The id of the swekey
|
||||
* @param rt The random token used to generate the otp
|
||||
* @param otp The otp generated by the swekey
|
||||
*
|
||||
* @return true or false
|
||||
* @access public
|
||||
*/
|
||||
function Swekey_CheckOtp($id, $rt, $otp)
|
||||
{
|
||||
global $gSwekeyCheckServer;
|
||||
$res = Swekey_HttpGet($gSwekeyCheckServer.'/CHECK-OTP/'.$id.'/'.$rt.'/'.$otp, $response_code);
|
||||
return $response_code == 200 && $res == "OK";
|
||||
}
|
||||
|
||||
/**
|
||||
* Values that are associated with a key.
|
||||
* The following values can be returned by the Swekey_GetStatus() function
|
||||
*/
|
||||
define("SWEKEY_STATUS_OK", 0);
|
||||
define("SWEKEY_STATUS_NOT_FOUND", 1); // The key does not exist in the db
|
||||
define("SWEKEY_STATUS_INACTIVE", 2); // The key has never been activated
|
||||
define("SWEKEY_STATUS_LOST", 3); // The user has lost his key
|
||||
define("SWEKEY_STATUS_STOLEN", 4); // The key was stolen
|
||||
define("SWEKEY_STATUS_FEE_DUE", 5); // The annual fee was not paid
|
||||
define("SWEKEY_STATUS_OBSOLETE", 6); // The hardware is no longer supported
|
||||
define("SWEKEY_STATUS_UNKOWN", 201); // We could not connect to the authentication server
|
||||
|
||||
/**
|
||||
* Values that are associated with a key.
|
||||
* The Javascript Api can also return the following values
|
||||
*/
|
||||
define("SWEKEY_STATUS_REPLACED", 100); // This key has been replaced by a backup key
|
||||
define("SWEKEY_STATUS_BACKUP_KEY", 101); // This key is a backup key that is not activated yet
|
||||
define("SWEKEY_STATUS_NOTPLUGGED", 200); // This key is not plugged in the computer
|
||||
|
||||
|
||||
/**
|
||||
* Return the text corresponding to the integer status of a key
|
||||
*
|
||||
* @param status The status
|
||||
*
|
||||
* @return The text corresponding to the status
|
||||
* @access public
|
||||
*/
|
||||
function Swekey_GetStatusStr($status)
|
||||
{
|
||||
switch($status)
|
||||
{
|
||||
case SWEKEY_STATUS_OK :
|
||||
return 'OK';
|
||||
case SWEKEY_STATUS_NOT_FOUND :
|
||||
return 'Key does not exist in the db';
|
||||
case SWEKEY_STATUS_INACTIVE :
|
||||
return 'Key not activated';
|
||||
case SWEKEY_STATUS_LOST :
|
||||
return 'Key was lost';
|
||||
case SWEKEY_STATUS_STOLEN :
|
||||
return 'Key was stolen';
|
||||
case SWEKEY_STATUS_FEE_DUE :
|
||||
return 'The annual fee was not paid';
|
||||
case SWEKEY_STATUS_OBSOLETE :
|
||||
return 'Key no longer supported';
|
||||
case SWEKEY_STATUS_REPLACED :
|
||||
return 'This key has been replaced by a backup key';
|
||||
case SWEKEY_STATUS_BACKUP_KEY :
|
||||
return 'This key is a backup key that is not activated yet';
|
||||
case SWEKEY_STATUS_NOTPLUGGED :
|
||||
return 'This key is not plugged in the computer';
|
||||
case SWEKEY_STATUS_UNKOWN :
|
||||
return 'Unknow Status, could not connect to the authentication server';
|
||||
}
|
||||
return 'unknown status '.$status;
|
||||
}
|
||||
|
||||
/**
|
||||
* If your web site requires a key to login you should check that the key
|
||||
* is still valid (has not been lost or stolen) before requiring it.
|
||||
* A key can be authenticated only if its status is SWEKEY_STATUS_OK
|
||||
*
|
||||
* @param id The id of the swekey
|
||||
*
|
||||
* @return The status of the swekey
|
||||
* @access public
|
||||
*/
|
||||
function Swekey_GetStatus($id)
|
||||
{
|
||||
global $gSwekeyStatusServer;
|
||||
$res = Swekey_HttpGet($gSwekeyStatusServer.'/GET-STATUS/'.$id, $response_code);
|
||||
if ($response_code == 200) {
|
||||
return intval($res);
|
||||
}
|
||||
return SWEKEY_STATUS_UNKOWN;
|
||||
}
|
||||
|
||||
?>
|
||||
@ -213,7 +213,7 @@ class ExportLatex extends ExportPlugin
|
||||
|
||||
$head = '% phpMyAdmin LaTeX Dump' . $crlf
|
||||
. '% version ' . PMA_VERSION . $crlf
|
||||
. '% http://www.phpmyadmin.net' . $crlf
|
||||
. '% https://www.phpmyadmin.net' . $crlf
|
||||
. '%' . $crlf
|
||||
. '% ' . __('Host') . ': ' . $cfg['Server']['host'];
|
||||
if (! empty($cfg['Server']['port'])) {
|
||||
|
||||
@ -344,7 +344,7 @@ class ExportMediawiki extends ExportPlugin
|
||||
// see http://www.mediawiki.org/wiki/Help:Formatting
|
||||
$comment = $this->_exportCRLF();
|
||||
$comment .= '<!--' . $this->_exportCRLF();
|
||||
$comment .= $text . $this->_exportCRLF();
|
||||
$comment .= htmlspecialchars($text) . $this->_exportCRLF();
|
||||
$comment .= '-->' . str_repeat($this->_exportCRLF(), 2);
|
||||
|
||||
return $comment;
|
||||
|
||||
@ -82,6 +82,18 @@ class ExportPhparray extends ExportPlugin
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes end of comment from a string
|
||||
*
|
||||
* @param string $string String to replace
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function commentString($string)
|
||||
{
|
||||
return strtr($string, '*/', '-');
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs export header
|
||||
*
|
||||
@ -119,9 +131,9 @@ class ExportPhparray extends ExportPlugin
|
||||
public function exportDBHeader ($db)
|
||||
{
|
||||
PMA_exportOutputHandler(
|
||||
'//' . $GLOBALS['crlf']
|
||||
. '// Database ' . PMA_Util::backquote($db)
|
||||
. $GLOBALS['crlf'] . '//' . $GLOBALS['crlf']
|
||||
'/**' . $GLOBALS['crlf']
|
||||
. ' * Database ' . $this->commentString(PMA_Util::backquote($db))
|
||||
. $GLOBALS['crlf'] . ' */' . $GLOBALS['crlf']
|
||||
);
|
||||
return true;
|
||||
}
|
||||
@ -192,9 +204,9 @@ class ExportPhparray extends ExportPlugin
|
||||
$buffer = '';
|
||||
$record_cnt = 0;
|
||||
// Output table name as comment
|
||||
$buffer .= $crlf . '// '
|
||||
. PMA_Util::backquote($db) . '.'
|
||||
. PMA_Util::backquote($table) . $crlf;
|
||||
$buffer .= $crlf . '/* '
|
||||
. $this->commentString(PMA_Util::backquote($db)) . '.'
|
||||
. $this->commentString(PMA_Util::backquote($table)) . ' */' . $crlf;
|
||||
$buffer .= '$' . $tablefixed . ' = array(';
|
||||
|
||||
while ($record = PMA_DBI_fetch_row($result)) {
|
||||
|
||||
@ -519,7 +519,16 @@ class ExportSql extends ExportPlugin
|
||||
&& $GLOBALS['sql_include_comments']
|
||||
) {
|
||||
// see http://dev.mysql.com/doc/refman/5.0/en/ansi-diff-comments.html
|
||||
return '--' . (empty($text) ? '' : ' ') . $text . $GLOBALS['crlf'];
|
||||
if (empty($text)) {
|
||||
return '--' . $GLOBALS['crlf'];
|
||||
} else {
|
||||
$lines = preg_split("/\\r\\n|\\r|\\n/", $text);
|
||||
$result = array();
|
||||
foreach ($lines as $line) {
|
||||
$result[] = '-- ' . $line . $GLOBALS['crlf'];
|
||||
}
|
||||
return implode('', $result);
|
||||
}
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
@ -605,7 +614,7 @@ class ExportSql extends ExportPlugin
|
||||
}
|
||||
$head = $this->_exportComment('phpMyAdmin SQL Dump')
|
||||
. $this->_exportComment('version ' . PMA_VERSION)
|
||||
. $this->_exportComment('http://www.phpmyadmin.net')
|
||||
. $this->_exportComment('https://www.phpmyadmin.net')
|
||||
. $this->_exportComment();
|
||||
$host_string = __('Host') . ': ' . $cfg['Server']['host'];
|
||||
if (! empty($cfg['Server']['port'])) {
|
||||
|
||||
@ -186,9 +186,9 @@ class ExportXml extends ExportPlugin
|
||||
. '<!--' . $crlf
|
||||
. '- phpMyAdmin XML Dump' . $crlf
|
||||
. '- version ' . PMA_VERSION . $crlf
|
||||
. '- http://www.phpmyadmin.net' . $crlf
|
||||
. '- https://www.phpmyadmin.net' . $crlf
|
||||
. '-' . $crlf
|
||||
. '- ' . __('Host') . ': ' . $cfg['Server']['host'];
|
||||
. '- ' . __('Host') . ': ' . htmlspecialchars($cfg['Server']['host']);
|
||||
if (! empty($cfg['Server']['port'])) {
|
||||
$head .= ':' . $cfg['Server']['port'];
|
||||
}
|
||||
@ -201,7 +201,7 @@ class ExportXml extends ExportPlugin
|
||||
|
||||
$head .= '<pma_xml_export version="1.0"'
|
||||
. (($export_struct)
|
||||
? ' xmlns:pma="http://www.phpmyadmin.net/some_doc_url/"'
|
||||
? ' xmlns:pma="https://www.phpmyadmin.net/some_doc_url/"'
|
||||
: '')
|
||||
. '>' . $crlf;
|
||||
|
||||
@ -230,7 +230,7 @@ class ExportXml extends ExportPlugin
|
||||
$head .= ' -->' . $crlf;
|
||||
$head .= ' <pma:structure_schemas>' . $crlf;
|
||||
$head .= ' <pma:database name="' . htmlspecialchars($db)
|
||||
. '" collation="' . $db_collation . '" charset="' . $db_charset
|
||||
. '" collation="' . htmlspecialchars($db_collation) . '" charset="' . htmlspecialchars($db_charset)
|
||||
. '">' . $crlf;
|
||||
|
||||
if (count($tables) == 0) {
|
||||
@ -262,7 +262,7 @@ class ExportXml extends ExportPlugin
|
||||
continue;
|
||||
}
|
||||
|
||||
$head .= ' <pma:' . $type . ' name="' . $table . '">'
|
||||
$head .= ' <pma:' . $type . ' name="' . htmlspecialchars($table) . '">'
|
||||
. $crlf;
|
||||
|
||||
$tbl = " " . htmlspecialchars($tbl);
|
||||
@ -280,7 +280,7 @@ class ExportXml extends ExportPlugin
|
||||
foreach ($triggers as $trigger) {
|
||||
$code = $trigger['create'];
|
||||
$head .= ' <pma:trigger name="'
|
||||
. $trigger['name'] . '">' . $crlf;
|
||||
. htmlspecialchars($trigger['name']) . '">' . $crlf;
|
||||
|
||||
// Do some formatting
|
||||
$code = substr(rtrim($code), 0, -3);
|
||||
@ -305,7 +305,7 @@ class ExportXml extends ExportPlugin
|
||||
if ($functions) {
|
||||
foreach ($functions as $function) {
|
||||
$head .= ' <pma:function name="'
|
||||
. $function . '">' . $crlf;
|
||||
. htmlspecialchars($function) . '">' . $crlf;
|
||||
|
||||
// Do some formatting
|
||||
$sql = PMA_DBI_get_definition($db, 'FUNCTION', $function);
|
||||
@ -330,7 +330,7 @@ class ExportXml extends ExportPlugin
|
||||
if ($procedures) {
|
||||
foreach ($procedures as $procedure) {
|
||||
$head .= ' <pma:procedure name="'
|
||||
. $procedure . '">' . $crlf;
|
||||
. htmlspecialchars($procedure) . '">' . $crlf;
|
||||
|
||||
// Do some formatting
|
||||
$sql = PMA_DBI_get_definition($db, 'PROCEDURE', $procedure);
|
||||
@ -387,7 +387,7 @@ class ExportXml extends ExportPlugin
|
||||
&& $GLOBALS['xml_export_contents']
|
||||
) {
|
||||
$head = ' <!--' . $crlf
|
||||
. ' - ' . __('Database') . ': ' . '\'' . $db . '\'' . $crlf
|
||||
. ' - ' . __('Database') . ': ' . '\'' . htmlspecialchars($db) . '\'' . $crlf
|
||||
. ' -->' . $crlf
|
||||
. ' <database name="' . htmlspecialchars($db) . '">' . $crlf;
|
||||
|
||||
@ -454,7 +454,7 @@ class ExportXml extends ExportPlugin
|
||||
}
|
||||
unset($i);
|
||||
|
||||
$buffer = ' <!-- ' . __('Table') . ' ' . $table . ' -->' . $crlf;
|
||||
$buffer = ' <!-- ' . __('Table') . ' ' . htmlspecialchars($table) . ' -->' . $crlf;
|
||||
if (! PMA_exportOutputHandler($buffer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -119,12 +119,15 @@ class ImportShp extends ImportPlugin
|
||||
// Extract the .dbf file and point to it.
|
||||
$extracted = PMA_zipExtract(
|
||||
$import_file,
|
||||
realpath($GLOBALS['cfg']['TempDir']),
|
||||
array($dbf_file_name)
|
||||
$dbf_file_name
|
||||
);
|
||||
if ($extracted) {
|
||||
if ($extracted !== false) {
|
||||
$dbf_file_path = realpath($GLOBALS['cfg']['TempDir'])
|
||||
. (PMA_IS_WINDOWS ? '\\' : '/') . $dbf_file_name;
|
||||
. (PMA_IS_WINDOWS ? '\\' : '/') . PMA_sanitizeFilename($dbf_file_name, true);
|
||||
$handle = fopen($dbf_file_path, 'wb');
|
||||
if ($handle !== false) {
|
||||
fwrite($handle, $extracted);
|
||||
fclose($handle);
|
||||
$temp_dbf_file = true;
|
||||
// Replace the .dbf with .*, as required
|
||||
// by the bsShapeFiles library.
|
||||
@ -134,6 +137,7 @@ class ImportShp extends ImportPlugin
|
||||
$shp->FileName = $file_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif (! empty($local_import_file)
|
||||
&& ! empty($GLOBALS['cfg']['UploadDir'])
|
||||
&& $compression == 'none'
|
||||
@ -148,6 +152,14 @@ class ImportShp extends ImportPlugin
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the .dbf file extracted to 'TempDir'
|
||||
if ($temp_dbf_file
|
||||
&& isset($dbf_file_path)
|
||||
&& file_exists($dbf_file_path)
|
||||
) {
|
||||
unlink($dbf_file_path);
|
||||
}
|
||||
|
||||
// Load data
|
||||
$shp->loadFromFile('');
|
||||
if ($shp->lastError != "") {
|
||||
@ -159,14 +171,6 @@ class ImportShp extends ImportPlugin
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete the .dbf file extracted to 'TempDir'
|
||||
if ($temp_dbf_file
|
||||
&& isset($dbf_file_path)
|
||||
&& file_exists($dbf_file_path)
|
||||
) {
|
||||
unlink($dbf_file_path);
|
||||
}
|
||||
|
||||
$esri_types = array(
|
||||
0 => 'Null Shape',
|
||||
1 => 'Point',
|
||||
|
||||
@ -49,7 +49,7 @@ abstract class AppendTransformationsPlugin extends TransformationsPlugin
|
||||
$options[0] = '';
|
||||
}
|
||||
//just append the option to the original text
|
||||
$newtext = $buffer . htmlspecialchars($options[0]);
|
||||
$newtext = htmlspecialchars($buffer) . htmlspecialchars($options[0]);
|
||||
|
||||
return $newtext;
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ if (! defined('PHPMYADMIN')) {
|
||||
|
||||
/* Get the transformations interface */
|
||||
require_once 'libraries/plugins/TransformationsPlugin.class.php';
|
||||
require_once 'libraries/js_escape.lib.php';
|
||||
|
||||
/**
|
||||
* Provides common methods for all of the date format transformations plugins.
|
||||
@ -139,11 +140,11 @@ abstract class DateFormatTransformationsPlugin extends TransformationsPlugin
|
||||
} else {
|
||||
$text = 'INVALID DATE TYPE';
|
||||
}
|
||||
$buffer = '<dfn onclick="alert(\'' . $source . '\');" title="'
|
||||
. $source . '">' . $text . '</dfn>';
|
||||
return '<dfn onclick="alert(\'' . PMA_jsFormat($source, false) . '\');" title="'
|
||||
. htmlspecialchars($source) . '">' . htmlspecialchars($text) . '</dfn>';
|
||||
} else {
|
||||
return htmlspecialchars($buffer);
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -72,7 +72,7 @@ abstract class DownloadTransformationsPlugin extends TransformationsPlugin
|
||||
'<a href="transformation_wrapper.php%s&ct=application'
|
||||
. '/octet-stream&cn=%s" title="%s">%s</a>',
|
||||
$options['wrapper_link'],
|
||||
urlencode($cn),
|
||||
htmlspecialchars(urlencode($cn)),
|
||||
htmlspecialchars($cn),
|
||||
htmlspecialchars($cn)
|
||||
);
|
||||
|
||||
@ -45,7 +45,9 @@ abstract class FormattedTransformationsPlugin extends TransformationsPlugin
|
||||
*/
|
||||
public function applyTransformation($buffer, $options = array(), $meta = '')
|
||||
{
|
||||
return $buffer;
|
||||
return '<iframe srcdoc="'
|
||||
. strtr($buffer, '"', '\'')
|
||||
. '" sandbox=""></iframe>';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -45,16 +45,8 @@ abstract class ImageLinkTransformationsPlugin extends TransformationsPlugin
|
||||
*/
|
||||
public function applyTransformation($buffer, $options = array(), $meta = '')
|
||||
{
|
||||
$transform_options = array (
|
||||
'string' => '<a href="transformation_wrapper.php'
|
||||
. $options['wrapper_link'] . '" alt="[__BUFFER__]">[BLOB]</a>'
|
||||
);
|
||||
$buffer = PMA_transformation_global_html_replace(
|
||||
$buffer,
|
||||
$transform_options
|
||||
);
|
||||
|
||||
return $buffer;
|
||||
return '<a href="transformation_wrapper.php'
|
||||
. $options['wrapper_link'] . '" alt="' . htmlspecialchars($buffer) . '">[BLOB]</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -47,28 +47,18 @@ abstract class InlineTransformationsPlugin extends TransformationsPlugin
|
||||
public function applyTransformation($buffer, $options = array(), $meta = '')
|
||||
{
|
||||
if (PMA_IS_GD2) {
|
||||
$transform_options = array (
|
||||
'string' => '<a href="transformation_wrapper.php'
|
||||
return '<a href="transformation_wrapper.php'
|
||||
. $options['wrapper_link']
|
||||
. '" target="_blank"><img src="transformation_wrapper.php'
|
||||
. '" rel="noopener noreferrer" target="_blank"><img src="transformation_wrapper.php'
|
||||
. $options['wrapper_link'] . '&resize=jpeg&newWidth='
|
||||
. (isset($options[0]) ? $options[0] : '100') . '&newHeight='
|
||||
. (isset($options[1]) ? $options[1] : 100)
|
||||
. '" alt="[__BUFFER__]" border="0" /></a>'
|
||||
);
|
||||
. (isset($options[0]) ? intval($options[0]) : '100') . '&newHeight='
|
||||
. (isset($options[1]) ? intval($options[1]) : 100)
|
||||
. '" alt="' . htmlspecialchars($buffer) . '" border="0" /></a>';
|
||||
} else {
|
||||
$transform_options = array (
|
||||
'string' => '<img src="transformation_wrapper.php'
|
||||
return '<img src="transformation_wrapper.php'
|
||||
. $options['wrapper_link']
|
||||
. '" alt="[__BUFFER__]" width="320" height="240" />'
|
||||
);
|
||||
. '" alt="' . htmlspecialchars($buffer) . '" width="320" height="240" />';
|
||||
}
|
||||
$buffer = PMA_transformation_global_html_replace(
|
||||
$buffer,
|
||||
$transform_options
|
||||
);
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -45,7 +45,7 @@ abstract class LongToIPv4TransformationsPlugin extends TransformationsPlugin
|
||||
public function applyTransformation($buffer, $options = array(), $meta = '')
|
||||
{
|
||||
if ($buffer < 0 || $buffer > 4294967295) {
|
||||
return $buffer;
|
||||
return htmlspecialchars($buffer);
|
||||
}
|
||||
|
||||
return long2ip($buffer);
|
||||
|
||||
@ -81,7 +81,7 @@ abstract class SubstringTransformationsPlugin extends TransformationsPlugin
|
||||
}
|
||||
}
|
||||
|
||||
return $newtext;
|
||||
return htmlspecialchars($newtext);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -12,8 +12,6 @@ if (! defined('PHPMYADMIN')) {
|
||||
|
||||
/* Get the transformations interface */
|
||||
require_once 'libraries/plugins/TransformationsPlugin.class.php';
|
||||
/* For PMA_transformation_global_html_replace */
|
||||
require_once 'libraries/transformations.lib.php';
|
||||
|
||||
/**
|
||||
* Provides common methods for all of the image link transformations plugins.
|
||||
@ -47,21 +45,17 @@ abstract class TextImageLinkTransformationsPlugin extends TransformationsPlugin
|
||||
*/
|
||||
public function applyTransformation($buffer, $options = array(), $meta = '')
|
||||
{
|
||||
$transform_options = array (
|
||||
'string' => '<a href="' . (isset($options[0]) ? $options[0] : '')
|
||||
. $buffer . '" target="_blank"><img src="'
|
||||
. (isset($options[0]) ? $options[0] : '') . $buffer
|
||||
. '" border="0" width="' . (isset($options[1]) ? $options[1] : 100)
|
||||
. '" height="' . (isset($options[2]) ? $options[2] : 50) . '" />'
|
||||
. $buffer . '</a>'
|
||||
);
|
||||
|
||||
$buffer = PMA_transformation_global_html_replace(
|
||||
$buffer,
|
||||
$transform_options
|
||||
);
|
||||
|
||||
return $buffer;
|
||||
$url = (isset($options[0]) ? $options[0] : '') . $buffer;
|
||||
$parsed = parse_url($url);
|
||||
/* Do not allow javascript links */
|
||||
if (! isset($parsed['scheme']) || ! in_array(strtolower($parsed['scheme']), array('http', 'https', 'ftp', 'mailto'))) {
|
||||
return htmlspecialchars($url);
|
||||
}
|
||||
return '<a href="' . htmlspecialchars($url)
|
||||
. '" rel="noopener noreferrer" target="_blank"><img src="' . htmlspecialchars($url)
|
||||
. '" border="0" width="' . (isset($options[1]) ? intval($options[1]) : 100)
|
||||
. '" height="' . (isset($options[2]) ? intval($options[2]) : 50) . '" />'
|
||||
. htmlspecialchars($buffer) . '</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -12,8 +12,6 @@ if (! defined('PHPMYADMIN')) {
|
||||
|
||||
/* Get the transformations interface */
|
||||
require_once 'libraries/plugins/TransformationsPlugin.class.php';
|
||||
/* For PMA_transformation_global_html_replace */
|
||||
require_once 'libraries/transformations.lib.php';
|
||||
|
||||
/**
|
||||
* Provides common methods for all of the link transformations plugins.
|
||||
@ -47,25 +45,19 @@ abstract class TextLinkTransformationsPlugin extends TransformationsPlugin
|
||||
*/
|
||||
public function applyTransformation($buffer, $options = array(), $meta = '')
|
||||
{
|
||||
|
||||
$append_part = (isset($options[2]) && $options[2]) ? '' : $buffer;
|
||||
|
||||
$transform_options = array (
|
||||
'string' => '<a href="'
|
||||
. PMA_linkURL((isset($options[0]) ? $options[0] : '') . $append_part)
|
||||
$url = (isset($options[0]) ? $options[0] : '') . ((isset($options[2]) && $options[2]) ? '' : $buffer);
|
||||
$parsed = parse_url($url);
|
||||
/* Do not allow javascript links */
|
||||
if (! isset($parsed['scheme']) || ! in_array(strtolower($parsed['scheme']), array('http', 'https', 'ftp', 'mailto'))) {
|
||||
return htmlspecialchars($url);
|
||||
}
|
||||
return '<a href="'
|
||||
. htmlspecialchars($url)
|
||||
. '" title="'
|
||||
. htmlspecialchars(isset($options[1]) ? $options[1] : '')
|
||||
. '" target="_new">'
|
||||
. '" target="_blank" rel="noopener noreferrer">'
|
||||
. htmlspecialchars(isset($options[1]) ? $options[1] : $buffer)
|
||||
. '</a>'
|
||||
);
|
||||
|
||||
$buffer = PMA_transformation_global_html_replace(
|
||||
$buffer,
|
||||
$transform_options
|
||||
);
|
||||
|
||||
return $buffer;
|
||||
. '</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -233,7 +233,7 @@ function PMA_replication_slave_change_master($user, $password, $host, $port,
|
||||
function PMA_replication_connect_to_master($user, $password, $host = null, $port = null, $socket = null)
|
||||
{
|
||||
$server = array();
|
||||
$server["host"] = $host;
|
||||
$server["host"] = PMA_sanitizeMySQLHost($host);
|
||||
$server["port"] = $port;
|
||||
$server["socket"] = $socket;
|
||||
|
||||
|
||||
@ -130,7 +130,7 @@ function PMA_replication_print_status_table($type, $hidden = false, $title = tru
|
||||
foreach (${"{$type}_variables"} as $variable) {
|
||||
echo ' <tr class="' . ($odd_row ? 'odd' : 'even') . '">';
|
||||
echo ' <td class="name">';
|
||||
echo $variable;
|
||||
echo htmlspecialchars($variable);
|
||||
echo ' </td>';
|
||||
echo ' <td class="value">';
|
||||
|
||||
@ -154,9 +154,9 @@ function PMA_replication_print_status_table($type, $hidden = false, $title = tru
|
||||
'Replicate_Do_Table', 'Replicate_Ignore_Table',
|
||||
'Replicate_Wild_Do_Table', 'Replicate_Wild_Ignore_Table');
|
||||
if (in_array($variable, $variables_wrap)) {
|
||||
echo str_replace(',', ', ', ${"server_{$type}_replication"}[0][$variable]);
|
||||
echo htmlspecialchars(str_replace(',', ', ', ${"server_{$type}_replication"}[0][$variable]));
|
||||
} else {
|
||||
echo ${"server_{$type}_replication"}[0][$variable];
|
||||
echo htmlspecialchars(${"server_{$type}_replication"}[0][$variable]);
|
||||
}
|
||||
echo '</span>';
|
||||
|
||||
@ -285,7 +285,7 @@ function PMA_replication_gui_master_addslaveuser()
|
||||
? ''
|
||||
: ' value="' . (isset($GLOBALS['new_username'])
|
||||
? $GLOBALS['new_username']
|
||||
: $GLOBALS['username']) . '"')
|
||||
: htmlspecialchars($GLOBALS['username'])) . '"')
|
||||
. ' onchange="pred_username.value = \'userdefined\';" />'
|
||||
. '</div>'
|
||||
. '<div class="item">'
|
||||
@ -349,7 +349,7 @@ function PMA_replication_gui_master_addslaveuser()
|
||||
. '</span>'
|
||||
. '<input type="text" name="hostname" maxlength="'
|
||||
. $hostname_length . '" value="'
|
||||
. (isset($GLOBALS['hostname']) ? $GLOBALS['hostname'] : '')
|
||||
. (isset($GLOBALS['hostname']) ? htmlspecialchars($GLOBALS['hostname']) : '')
|
||||
. '" title="' . __('Host')
|
||||
. '" onchange="pred_hostname.value = \'userdefined\';" />'
|
||||
. PMA_Util::showHint(
|
||||
|
||||
@ -249,8 +249,8 @@ function PMA_TRI_getRowForList($trigger, $rowclass = '')
|
||||
if (empty($table)) {
|
||||
$retval .= " <td>\n";
|
||||
$retval .= "<a href='db_triggers.php?{$url_query}"
|
||||
. "&table={$trigger['table']}'>"
|
||||
. $trigger['table'] . "</a>\n";
|
||||
. "&table=" . urlencode($trigger['table']) . "'>"
|
||||
. urlencode($trigger['table']) . "</a>";
|
||||
$retval .= " </td>\n";
|
||||
}
|
||||
$retval .= " <td>\n";
|
||||
|
||||
@ -59,6 +59,9 @@ function PMA_replaceBBLink($found)
|
||||
$target = '';
|
||||
if (! empty($found[3])) {
|
||||
$target = ' target="' . $found[3] . '"';
|
||||
if ($found[3] == '_blank') {
|
||||
$target .= ' rel="noopener noreferrer"';
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct url */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user