plugins and OOP: import XML, export and import SQL; auth structure
This commit is contained in:
parent
a87f283a23
commit
b0e8486ef1
71
libraries/plugins/auth/AuthenticationConfig.class.php
Normal file
71
libraries/plugins/auth/AuthenticationConfig.class.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* Config Authentication plugin for phpMyAdmin
|
||||
*
|
||||
* @package PhpMyAdmin-Authentication
|
||||
* @subpackage Config
|
||||
*/
|
||||
if (! defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/* Get the authentication interface */
|
||||
require_once "libraries/plugins/AuthenticationPlugin.class.php";
|
||||
|
||||
/**
|
||||
* Handles the config authentication method
|
||||
*
|
||||
* @package PhpMyAdmin-Authentication
|
||||
*/
|
||||
class AuthenticationConfig extends AuthenticationPlugin
|
||||
{
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function auth()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function authCheck()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function authSetUser()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function authFails()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when any PluginManager to which the observer
|
||||
* is attached calls PluginManager::notify()
|
||||
*
|
||||
* @param SplSubject $subject The PluginManager notifying the observer
|
||||
* of an update.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function update (SplSubject $subject)
|
||||
{
|
||||
}
|
||||
}
|
||||
89
libraries/plugins/auth/AuthenticationCookie.class.php
Normal file
89
libraries/plugins/auth/AuthenticationCookie.class.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* Cookie Authentication plugin for phpMyAdmin
|
||||
*
|
||||
* @package PhpMyAdmin-Authentication
|
||||
* @subpackage Cookie
|
||||
*/
|
||||
if (! defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/* Get the authentication interface */
|
||||
require_once "libraries/plugins/AuthenticationPlugin.class.php";
|
||||
|
||||
/**
|
||||
* Handles the cookie authentication method
|
||||
*
|
||||
* @package PhpMyAdmin-Authentication
|
||||
*/
|
||||
class AuthenticationCookie extends AuthenticationPlugin
|
||||
{
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function auth()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function authCheck()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function authSetUser()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function authFails()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function blowfishEncrypt()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function blowfishDecrypt()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when any PluginManager to which the observer
|
||||
* is attached calls PluginManager::notify()
|
||||
*
|
||||
* @param SplSubject $subject The PluginManager notifying the observer
|
||||
* of an update.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function update (SplSubject $subject)
|
||||
{
|
||||
}
|
||||
}
|
||||
71
libraries/plugins/auth/AuthenticationHTTP.class.php
Normal file
71
libraries/plugins/auth/AuthenticationHTTP.class.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* HTTP Authentication plugin for phpMyAdmin
|
||||
*
|
||||
* @package PhpMyAdmin-Authentication
|
||||
* @subpackage Config
|
||||
*/
|
||||
if (! defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/* Get the authentication interface */
|
||||
require_once "libraries/plugins/AuthenticationPlugin.class.php";
|
||||
|
||||
/**
|
||||
* Handles the HTTP authentication method
|
||||
*
|
||||
* @package PhpMyAdmin-Authentication
|
||||
*/
|
||||
class AuthenticationHTTP extends AuthenticationPlugin
|
||||
{
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function auth()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function authCheck()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function authSetUser()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function authFails()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when any PluginManager to which the observer
|
||||
* is attached calls PluginManager::notify()
|
||||
*
|
||||
* @param SplSubject $subject The PluginManager notifying the observer
|
||||
* of an update.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function update (SplSubject $subject)
|
||||
{
|
||||
}
|
||||
}
|
||||
71
libraries/plugins/auth/AuthenticationSIgnOn.class.php
Normal file
71
libraries/plugins/auth/AuthenticationSIgnOn.class.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* SignOn Authentication plugin for phpMyAdmin
|
||||
*
|
||||
* @package PhpMyAdmin-Authentication
|
||||
* @subpackage SignOn
|
||||
*/
|
||||
if (! defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/* Get the authentication interface */
|
||||
require_once "libraries/plugins/AuthenticationPlugin.class.php";
|
||||
|
||||
/**
|
||||
* Handles the SignOn authentication method
|
||||
*
|
||||
* @package PhpMyAdmin-Authentication
|
||||
*/
|
||||
class AuthenticationSignOn extends AuthenticationPlugin
|
||||
{
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function auth()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function authCheck()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function authSetUser()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function authFails()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when any PluginManager to which the observer
|
||||
* is attached calls PluginManager::notify()
|
||||
*
|
||||
* @param SplSubject $subject The PluginManager notifying the observer
|
||||
* of an update.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function update (SplSubject $subject)
|
||||
{
|
||||
}
|
||||
}
|
||||
172
libraries/plugins/auth/swekey/authentication.inc.php
Normal file
172
libraries/plugins/auth/swekey/authentication.inc.php
Normal file
@ -0,0 +1,172 @@
|
||||
<?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>
|
||||
25
libraries/plugins/auth/swekey/musbe-ca.crt
Normal file
25
libraries/plugins/auth/swekey/musbe-ca.crt
Normal file
@ -0,0 +1,25 @@
|
||||
-----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-----
|
||||
291
libraries/plugins/auth/swekey/swekey.auth.lib.php
Normal file
291
libraries/plugins/auth/swekey/swekey.auth.lib.php
Normal file
@ -0,0 +1,291 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Swekey
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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/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/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']);
|
||||
}
|
||||
|
||||
?>
|
||||
517
libraries/plugins/auth/swekey/swekey.php
Normal file
517
libraries/plugins/auth/swekey/swekey.php
Normal file
@ -0,0 +1,517 @@
|
||||
<?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;
|
||||
}
|
||||
|
||||
?>
|
||||
1886
libraries/plugins/export/ExportSQL.class.php
Normal file
1886
libraries/plugins/export/ExportSQL.class.php
Normal file
File diff suppressed because it is too large
Load Diff
392
libraries/plugins/import/ImportSQL.class.php
Normal file
392
libraries/plugins/import/ImportSQL.class.php
Normal file
@ -0,0 +1,392 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* SQL import plugin for phpMyAdmin
|
||||
*
|
||||
* @package PhpMyAdmin-Import
|
||||
* @subpackage SQL
|
||||
*/
|
||||
if (! defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/* Get the import interface */
|
||||
require_once "libraries/plugins/ImportPlugin.class.php";
|
||||
|
||||
/**
|
||||
* Handles the import for the SQL format
|
||||
*
|
||||
* @package PhpMyAdmin-Import
|
||||
*/
|
||||
class ImportSQL extends ImportPlugin
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->setProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the import plugin properties.
|
||||
* Called in the constructor.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setProperties()
|
||||
{
|
||||
$this->properties = array(
|
||||
'text' => __('SQL'),
|
||||
'extension' => 'sql',
|
||||
'options' => array(),
|
||||
'options_text' => __('Options'),
|
||||
);
|
||||
|
||||
$compats = PMA_DBI_getCompatibilities();
|
||||
if (count($compats) > 0) {
|
||||
$values = array();
|
||||
foreach ($compats as $val) {
|
||||
$values[$val] = $val;
|
||||
}
|
||||
$this->properties['options'] = array(
|
||||
array('type' => 'begin_group', 'name' => 'general_opts'),
|
||||
array(
|
||||
'type' => 'select',
|
||||
'name' => 'compatibility',
|
||||
'text' => __('SQL compatibility mode:'),
|
||||
'values' => $values,
|
||||
'doc' => array(
|
||||
'manual_MySQL_Database_Administration',
|
||||
'Server_SQL_mode',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'bool',
|
||||
'name' => 'no_auto_value_on_zero',
|
||||
'text' => __('Do not use <code>AUTO_INCREMENT</code> for zero values'),
|
||||
'doc' => array(
|
||||
'manual_MySQL_Database_Administration',
|
||||
'Server_SQL_mode',
|
||||
'sqlmode_no_auto_value_on_zero'
|
||||
),
|
||||
|
||||
),
|
||||
array('type' => 'end_group'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when any PluginManager to which the observer
|
||||
* is attached calls PluginManager::notify()
|
||||
*
|
||||
* @param SplSubject $subject The PluginManager notifying the observer
|
||||
* of an update.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function update (SplSubject $subject)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the whole import logic
|
||||
*/
|
||||
public function doImport()
|
||||
{
|
||||
// initialize the general import variables
|
||||
$this->initImportCommonVariables();
|
||||
|
||||
$error = $this->getError();
|
||||
$timeout_passed = $this->getTimeout_passed();
|
||||
|
||||
$buffer = '';
|
||||
// Defaults for parser
|
||||
$sql = '';
|
||||
$start_pos = 0;
|
||||
$i = 0;
|
||||
$len= 0;
|
||||
$big_value = 2147483647;
|
||||
$delimiter_keyword = 'DELIMITER '; // include the space because it's mandatory
|
||||
$length_of_delimiter_keyword = strlen($delimiter_keyword);
|
||||
|
||||
if (isset($_POST['sql_delimiter'])) {
|
||||
$sql_delimiter = $_POST['sql_delimiter'];
|
||||
} else {
|
||||
$sql_delimiter = ';';
|
||||
}
|
||||
|
||||
// Handle compatibility options
|
||||
$sql_modes = array();
|
||||
if (isset($_REQUEST['sql_compatibility'])
|
||||
&& 'NONE' != $_REQUEST['sql_compatibility']
|
||||
) {
|
||||
$sql_modes[] = $_REQUEST['sql_compatibility'];
|
||||
}
|
||||
if (isset($_REQUEST['sql_no_auto_value_on_zero'])) {
|
||||
$sql_modes[] = 'NO_AUTO_VALUE_ON_ZERO';
|
||||
}
|
||||
if (count($sql_modes) > 0) {
|
||||
PMA_DBI_try_query('SET SQL_MODE="' . implode(',', $sql_modes) . '"');
|
||||
}
|
||||
unset($sql_modes);
|
||||
|
||||
/**
|
||||
* will be set in PMA_importGetNextChunk()
|
||||
*
|
||||
* @global boolean $GLOBALS['finished']
|
||||
*/
|
||||
$GLOBALS['finished'] = false;
|
||||
|
||||
while (! ($GLOBALS['finished'] && $i >= $len) && ! $error && ! $timeout_passed) {
|
||||
$data = PMA_importGetNextChunk();
|
||||
if ($data === false) {
|
||||
// subtract data we didn't handle yet and stop processing
|
||||
$offset -= strlen($buffer);
|
||||
break;
|
||||
} elseif ($data === true) {
|
||||
// Handle rest of buffer
|
||||
} else {
|
||||
// Append new data to buffer
|
||||
$buffer .= $data;
|
||||
// free memory
|
||||
unset($data);
|
||||
// Do not parse string when we're not at the end and don't have ; inside
|
||||
if ((strpos($buffer, $sql_delimiter, $i) === false)
|
||||
&& ! $GLOBALS['finished']
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Current length of our buffer
|
||||
$len = strlen($buffer);
|
||||
|
||||
// Grab some SQL queries out of it
|
||||
while ($i < $len) {
|
||||
$found_delimiter = false;
|
||||
// Find first interesting character
|
||||
$old_i = $i;
|
||||
// this is about 7 times faster that looking for each sequence i
|
||||
// one by one with strpos()
|
||||
$match = preg_match(
|
||||
'/(\'|"|#|-- |\/\*|`|(?i)(?<![A-Z0-9_])' . $delimiter_keyword . ')/',
|
||||
$buffer,
|
||||
$matches,
|
||||
PREG_OFFSET_CAPTURE,
|
||||
$i
|
||||
);
|
||||
if ($match) {
|
||||
// in $matches, index 0 contains the match for the complete
|
||||
// expression but we don't use it
|
||||
$first_position = $matches[1][1];
|
||||
} else {
|
||||
$first_position = $big_value;
|
||||
}
|
||||
/**
|
||||
* @todo we should not look for a delimiter that might be
|
||||
* inside quotes (or even double-quotes)
|
||||
*/
|
||||
// the cost of doing this one with preg_match() would be too high
|
||||
$first_sql_delimiter = strpos($buffer, $sql_delimiter, $i);
|
||||
if ($first_sql_delimiter === false) {
|
||||
$first_sql_delimiter = $big_value;
|
||||
} else {
|
||||
$found_delimiter = true;
|
||||
}
|
||||
|
||||
// set $i to the position of the first quote,
|
||||
// comment.start or delimiter found
|
||||
$i = min($first_position, $first_sql_delimiter);
|
||||
|
||||
if ($i == $big_value) {
|
||||
// none of the above was found in the string
|
||||
|
||||
$i = $old_i;
|
||||
if (!$GLOBALS['finished']) {
|
||||
break;
|
||||
}
|
||||
// at the end there might be some whitespace...
|
||||
if (trim($buffer) == '') {
|
||||
$buffer = '';
|
||||
$len = 0;
|
||||
break;
|
||||
}
|
||||
// We hit end of query, go there!
|
||||
$i = strlen($buffer) - 1;
|
||||
}
|
||||
|
||||
// Grab current character
|
||||
$ch = $buffer[$i];
|
||||
|
||||
// Quotes
|
||||
if (strpos('\'"`', $ch) !== false) {
|
||||
$quote = $ch;
|
||||
$endq = false;
|
||||
while (!$endq) {
|
||||
// Find next quote
|
||||
$pos = strpos($buffer, $quote, $i + 1);
|
||||
/*
|
||||
* Behave same as MySQL and accept end of query as end of backtick.
|
||||
* I know this is sick, but MySQL behaves like this:
|
||||
*
|
||||
* SELECT * FROM `table
|
||||
*
|
||||
* is treated like
|
||||
*
|
||||
* SELECT * FROM `table`
|
||||
*/
|
||||
if ($pos === false && $quote == '`' && $found_delimiter) {
|
||||
$pos = $first_sql_delimiter - 1;
|
||||
} elseif ($pos === false) { // No quote? Too short string
|
||||
// We hit end of string => unclosed quote,
|
||||
// but we handle it as end of query
|
||||
if ($GLOBALS['finished']) {
|
||||
$endq = true;
|
||||
$i = $len - 1;
|
||||
}
|
||||
$found_delimiter = false;
|
||||
break;
|
||||
}
|
||||
// Was not the quote escaped?
|
||||
$j = $pos - 1;
|
||||
while ($buffer[$j] == '\\') {
|
||||
$j--;
|
||||
}
|
||||
// Even count means it was not escaped
|
||||
$endq = (((($pos - 1) - $j) % 2) == 0);
|
||||
// Skip the string
|
||||
$i = $pos;
|
||||
|
||||
if ($first_sql_delimiter < $pos) {
|
||||
$found_delimiter = false;
|
||||
}
|
||||
}
|
||||
if (!$endq) {
|
||||
break;
|
||||
}
|
||||
$i++;
|
||||
// Aren't we at the end?
|
||||
if ($GLOBALS['finished'] && $i == $len) {
|
||||
$i--;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Not enough data to decide
|
||||
if ((($i == ($len - 1) && ($ch == '-' || $ch == '/'))
|
||||
|| ($i == ($len - 2) && (($ch == '-' && $buffer[$i + 1] == '-')
|
||||
|| ($ch == '/' && $buffer[$i + 1] == '*')))) && !$GLOBALS['finished']
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Comments
|
||||
if ($ch == '#'
|
||||
|| ($i < ($len - 1) && $ch == '-' && $buffer[$i + 1] == '-'
|
||||
&& (($i < ($len - 2) && $buffer[$i + 2] <= ' ')
|
||||
|| ($i == ($len - 1) && $GLOBALS['finished'])))
|
||||
|| ($i < ($len - 1) && $ch == '/' && $buffer[$i + 1] == '*')
|
||||
) {
|
||||
// Copy current string to SQL
|
||||
if ($start_pos != $i) {
|
||||
$sql .= substr($buffer, $start_pos, $i - $start_pos);
|
||||
}
|
||||
// Skip the rest
|
||||
$start_of_comment = $i;
|
||||
// do not use PHP_EOL here instead of "\n", because the export
|
||||
// file might have been produced on a different system
|
||||
$i = strpos($buffer, $ch == '/' ? '*/' : "\n", $i);
|
||||
// didn't we hit end of string?
|
||||
if ($i === false) {
|
||||
if ($GLOBALS['finished']) {
|
||||
$i = $len - 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Skip *
|
||||
if ($ch == '/') {
|
||||
$i++;
|
||||
}
|
||||
// Skip last char
|
||||
$i++;
|
||||
// We need to send the comment part in case we are defining
|
||||
// a procedure or function and comments in it are valuable
|
||||
$sql .= substr($buffer, $start_of_comment, $i - $start_of_comment);
|
||||
// Next query part will start here
|
||||
$start_pos = $i;
|
||||
// Aren't we at the end?
|
||||
if ($i == $len) {
|
||||
$i--;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Change delimiter, if redefined, and skip it (don't send to server!)
|
||||
if (strtoupper(substr($buffer, $i, $length_of_delimiter_keyword)) == $delimiter_keyword
|
||||
&& ($i + $length_of_delimiter_keyword < $len)
|
||||
) {
|
||||
// look for EOL on the character immediately after 'DELIMITER '
|
||||
// (see previous comment about PHP_EOL)
|
||||
$new_line_pos = strpos($buffer, "\n", $i + $length_of_delimiter_keyword);
|
||||
// it might happen that there is no EOL
|
||||
if (false === $new_line_pos) {
|
||||
$new_line_pos = $len;
|
||||
}
|
||||
$sql_delimiter = substr(
|
||||
$buffer,
|
||||
$i + $length_of_delimiter_keyword,
|
||||
$new_line_pos - $i - $length_of_delimiter_keyword
|
||||
);
|
||||
$i = $new_line_pos + 1;
|
||||
// Next query part will start here
|
||||
$start_pos = $i;
|
||||
continue;
|
||||
}
|
||||
|
||||
// End of SQL
|
||||
if ($found_delimiter || ($GLOBALS['finished'] && ($i == $len - 1))) {
|
||||
$tmp_sql = $sql;
|
||||
if ($start_pos < $len) {
|
||||
$length_to_grab = $i - $start_pos;
|
||||
|
||||
if (! $found_delimiter) {
|
||||
$length_to_grab++;
|
||||
}
|
||||
$tmp_sql .= substr($buffer, $start_pos, $length_to_grab);
|
||||
unset($length_to_grab);
|
||||
}
|
||||
// Do not try to execute empty SQL
|
||||
if (! preg_match('/^([\s]*;)*$/', trim($tmp_sql))) {
|
||||
$sql = $tmp_sql;
|
||||
PMA_importRunQuery(
|
||||
$sql,
|
||||
substr($buffer, 0, $i + strlen($sql_delimiter))
|
||||
);
|
||||
$buffer = substr($buffer, $i + strlen($sql_delimiter));
|
||||
// Reset parser:
|
||||
$len = strlen($buffer);
|
||||
$sql = '';
|
||||
$i = 0;
|
||||
$start_pos = 0;
|
||||
// Any chance we will get a complete query?
|
||||
//if ((strpos($buffer, ';') === false) && !$GLOBALS['finished']) {
|
||||
if (strpos($buffer, $sql_delimiter) === false
|
||||
&& ! $GLOBALS['finished']
|
||||
) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$i++;
|
||||
$start_pos = $i;
|
||||
}
|
||||
}
|
||||
} // End of parser loop
|
||||
} // End of import loop
|
||||
// Commit any possible data in buffers
|
||||
PMA_importRunQuery('', substr($buffer, 0, $len));
|
||||
PMA_importRunQuery();
|
||||
}
|
||||
}
|
||||
458
libraries/plugins/import/ImportXML.class.php
Normal file
458
libraries/plugins/import/ImportXML.class.php
Normal file
@ -0,0 +1,458 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* XML import plugin for phpMyAdmin
|
||||
*
|
||||
* @todo Improve efficiency
|
||||
* @package PhpMyAdmin-Import
|
||||
* @subpackage XML
|
||||
*/
|
||||
|
||||
if (! defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* We need way to disable external XML entities processing.
|
||||
*/
|
||||
if (!function_exists('libxml_disable_entity_loader')) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the import interface */
|
||||
require_once "libraries/plugins/ImportPlugin.class.php";
|
||||
|
||||
/**
|
||||
* Handles the import for the XML format
|
||||
*
|
||||
* @todo add descriptions
|
||||
* @package PhpMyAdmin-Import
|
||||
*/
|
||||
class ImportXML extends ImportPlugin
|
||||
{
|
||||
/**
|
||||
* Database name
|
||||
*
|
||||
* @var type String
|
||||
*/
|
||||
private $db = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var type
|
||||
*/
|
||||
private $table = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var type
|
||||
*/
|
||||
private $tables = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->setProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the local variables that are used specific for import XML
|
||||
*
|
||||
* @global type $table
|
||||
* @global type $tables
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function initLocalVariables()
|
||||
{
|
||||
global $table;
|
||||
global $tables;
|
||||
$this->setTable($table);
|
||||
$this->setTables($tables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the import plugin properties.
|
||||
* Called in the constructor.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setProperties()
|
||||
{
|
||||
$this->properties = array(
|
||||
'text' => __('XML'),
|
||||
'extension' => 'xml',
|
||||
'mime_type' => 'text/xml',
|
||||
'options' => array(),
|
||||
'options_text' => __('Options')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when any PluginManager to which the observer
|
||||
* is attached calls PluginManager::notify()
|
||||
*
|
||||
* @param SplSubject $subject The PluginManager notifying the observer
|
||||
* of an update.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function update (SplSubject $subject)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the whole import logic
|
||||
*/
|
||||
public function doImport()
|
||||
{
|
||||
// initialize the general import variables
|
||||
$this->initImportCommonVariables();
|
||||
|
||||
// initialize the specific import xml variables
|
||||
$this->initLocalVariables();
|
||||
|
||||
$error = $this->getError();
|
||||
$timeout_passed = $this->getTimeout_passed();
|
||||
$db = $this->getDb();
|
||||
// this is used in other functions while doImport() is being run
|
||||
global $finished;
|
||||
|
||||
$i = 0;
|
||||
$len = 0;
|
||||
$buffer = "";
|
||||
|
||||
/**
|
||||
* Read in the file via PMA_importGetNextChunk so that
|
||||
* it can process compressed files
|
||||
*/
|
||||
while (! ($finished && $i >= $len) && ! $error && ! $timeout_passed) {
|
||||
$data = PMA_importGetNextChunk();
|
||||
if ($data === false) {
|
||||
/* subtract data we didn't handle yet and stop processing */
|
||||
$offset -= strlen($buffer);
|
||||
break;
|
||||
} elseif ($data === true) {
|
||||
/* Handle rest of buffer */
|
||||
} else {
|
||||
/* Append new data to buffer */
|
||||
$buffer .= $data;
|
||||
unset($data);
|
||||
}
|
||||
}
|
||||
|
||||
unset($data);
|
||||
|
||||
/**
|
||||
* Disable loading of external XML entities.
|
||||
*/
|
||||
libxml_disable_entity_loader();
|
||||
|
||||
/**
|
||||
* Load the XML string
|
||||
*
|
||||
* The option LIBXML_COMPACT is specified because it can
|
||||
* result in increased performance without the need to
|
||||
* alter the code in any way. It's basically a freebee.
|
||||
*/
|
||||
$xml = simplexml_load_string($buffer, "SimpleXMLElement", LIBXML_COMPACT);
|
||||
|
||||
unset($buffer);
|
||||
|
||||
/**
|
||||
* The XML was malformed
|
||||
*/
|
||||
if ($xml === false) {
|
||||
PMA_Message::error(__(
|
||||
'The XML file specified was either malformed or incomplete.'
|
||||
. ' Please correct the issue and try again.'
|
||||
))->display();
|
||||
unset($xml);
|
||||
$GLOBALS['finished'] = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Table accumulator
|
||||
*/
|
||||
$tables = array();
|
||||
/**
|
||||
* Row accumulator
|
||||
*/
|
||||
$rows = array();
|
||||
|
||||
/**
|
||||
* Temp arrays
|
||||
*/
|
||||
$tempRow = array();
|
||||
$tempCells = array();
|
||||
|
||||
/**
|
||||
* CREATE code included (by default: no)
|
||||
*/
|
||||
$struct_present = false;
|
||||
|
||||
/**
|
||||
* Analyze the data in each table
|
||||
*/
|
||||
$namespaces = $xml->getNameSpaces(true);
|
||||
|
||||
/**
|
||||
* Get the database name, collation and charset
|
||||
*/
|
||||
$db_attr = $xml->children($namespaces['pma'])->{'structure_schemas'}->{'database'};
|
||||
|
||||
if ($db_attr instanceof SimpleXMLElement) {
|
||||
$db_attr = $db_attr->attributes();
|
||||
$db_name = (string)$db_attr['name'];
|
||||
$collation = (string)$db_attr['collation'];
|
||||
$charset = (string)$db_attr['charset'];
|
||||
} else {
|
||||
/**
|
||||
* If the structure section is not present
|
||||
* get the database name from the data section
|
||||
*/
|
||||
$db_attr = $xml->children()->attributes();
|
||||
$db_name = (string)$db_attr['name'];
|
||||
$collation = null;
|
||||
$charset = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The XML was malformed
|
||||
*/
|
||||
if ($db_name === null) {
|
||||
PMA_Message::error(__(
|
||||
'The XML file specified was either malformed or incomplete.'
|
||||
. ' Please correct the issue and try again.'
|
||||
))->display();
|
||||
unset($xml);
|
||||
$GLOBALS['finished'] = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the structure information
|
||||
*/
|
||||
if (isset($namespaces['pma'])) {
|
||||
/**
|
||||
* Get structures for all tables
|
||||
*/
|
||||
$struct = $xml->children($namespaces['pma']);
|
||||
|
||||
$create = array();
|
||||
|
||||
foreach ($struct as $tier1 => $val1) {
|
||||
foreach ($val1 as $tier2 => $val2) {
|
||||
// Need to select the correct database for the creation of tables,
|
||||
// views, triggers, etc.
|
||||
/**
|
||||
* @todo Generating a USE here blocks importing of a table
|
||||
* into another database.
|
||||
*/
|
||||
$attrs = $val2->attributes();
|
||||
$create[] = "USE " . PMA_backquote($attrs["name"]);
|
||||
|
||||
foreach ($val2 as $val3) {
|
||||
/**
|
||||
* Remove the extra cosmetic spacing
|
||||
*/
|
||||
$val3 = str_replace(" ", "", (string)$val3);
|
||||
$create[] = $val3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$struct_present = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move down the XML tree to the actual data
|
||||
*/
|
||||
$xml = $xml->children()->children();
|
||||
|
||||
$data_present = false;
|
||||
|
||||
/**
|
||||
* Only attempt to analyze/collect data if there is data present
|
||||
*/
|
||||
if ($xml && @$xml->count()) {
|
||||
$data_present = true;
|
||||
|
||||
/**
|
||||
* Process all database content
|
||||
*/
|
||||
foreach ($xml as $k1 => $v1) {
|
||||
$tbl_attr = $v1->attributes();
|
||||
|
||||
$isInTables = false;
|
||||
for ($i = 0; $i < count($tables); ++$i) {
|
||||
if (! strcmp($tables[$i][TBL_NAME], (string)$tbl_attr['name'])) {
|
||||
$isInTables = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($isInTables == false) {
|
||||
$tables[] = array((string)$tbl_attr['name']);
|
||||
}
|
||||
|
||||
foreach ($v1 as $k2 => $v2) {
|
||||
$row_attr = $v2->attributes();
|
||||
if (! array_search((string)$row_attr['name'], $tempRow)) {
|
||||
$tempRow[] = (string)$row_attr['name'];
|
||||
}
|
||||
$tempCells[] = (string)$v2;
|
||||
}
|
||||
|
||||
$rows[] = array((string)$tbl_attr['name'], $tempRow, $tempCells);
|
||||
|
||||
$tempRow = array();
|
||||
$tempCells = array();
|
||||
}
|
||||
|
||||
unset($tempRow);
|
||||
unset($tempCells);
|
||||
unset($xml);
|
||||
|
||||
/**
|
||||
* Bring accumulated rows into the corresponding table
|
||||
*/
|
||||
$num_tbls = count($tables);
|
||||
for ($i = 0; $i < $num_tbls; ++$i) {
|
||||
for ($j = 0; $j < count($rows); ++$j) {
|
||||
if (! strcmp($tables[$i][TBL_NAME], $rows[$j][TBL_NAME])) {
|
||||
if (! isset($tables[$i][COL_NAMES])) {
|
||||
$tables[$i][] = $rows[$j][COL_NAMES];
|
||||
}
|
||||
|
||||
$tables[$i][ROWS][] = $rows[$j][ROWS];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($rows);
|
||||
|
||||
if (! $struct_present) {
|
||||
$analyses = array();
|
||||
|
||||
$len = count($tables);
|
||||
for ($i = 0; $i < $len; ++$i) {
|
||||
$analyses[] = PMA_analyzeTable($tables[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($xml);
|
||||
unset($tempRows);
|
||||
unset($tempCells);
|
||||
unset($rows);
|
||||
|
||||
/**
|
||||
* Only build SQL from data if there is data present
|
||||
*/
|
||||
if ($data_present) {
|
||||
/**
|
||||
* Set values to NULL if they were not present
|
||||
* to maintain PMA_buildSQL() call integrity
|
||||
*/
|
||||
if (! isset($analyses)) {
|
||||
$analyses = null;
|
||||
if (! $struct_present) {
|
||||
$create = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* string $db_name (no backquotes)
|
||||
*
|
||||
* array $table = array(table_name, array() column_names, array()() rows)
|
||||
* array $tables = array of "$table"s
|
||||
*
|
||||
* array $analysis = array(array() column_types, array() column_sizes)
|
||||
* array $analyses = array of "$analysis"s
|
||||
*
|
||||
* array $create = array of SQL strings
|
||||
*
|
||||
* array $options = an associative array of options
|
||||
*/
|
||||
|
||||
/* Set database name to the currently selected one, if applicable */
|
||||
if (strlen($db)) {
|
||||
/* Override the database name in the XML file, if one is selected */
|
||||
$db_name = $db;
|
||||
$options = array('create_db' => false);
|
||||
} else {
|
||||
if ($db_name === null) {
|
||||
$db_name = 'XML_DB';
|
||||
}
|
||||
|
||||
/* Set database collation/charset */
|
||||
$options = array(
|
||||
'db_collation' => $collation,
|
||||
'db_charset' => $charset,
|
||||
);
|
||||
}
|
||||
|
||||
/* Created and execute necessary SQL statements from data */
|
||||
PMA_buildSQL($db_name, $tables, $analyses, $create, $options);
|
||||
|
||||
unset($analyses);
|
||||
unset($tables);
|
||||
unset($create);
|
||||
|
||||
/* Commit any possible data in buffers */
|
||||
PMA_importRunQuery();
|
||||
}
|
||||
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
|
||||
/**
|
||||
* Gets the database name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDb()
|
||||
{
|
||||
return $this->db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the database name
|
||||
*
|
||||
* @param String $db database name
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDb($db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
private function getTable()
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
private function setTable($table)
|
||||
{
|
||||
$this->table = $table;
|
||||
}
|
||||
|
||||
private function getTables()
|
||||
{
|
||||
return $this->tables;
|
||||
}
|
||||
|
||||
private function setTables($tables)
|
||||
{
|
||||
$this->tables = $tables;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user