plugins and OOP: import XML, export and import SQL; auth structure

This commit is contained in:
Alex Marin 2012-05-28 00:59:49 +03:00
parent a87f283a23
commit b0e8486ef1
11 changed files with 4043 additions and 0 deletions

View 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)
{
}
}

View 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)
{
}
}

View 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)
{
}
}

View 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)
{
}
}

View 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>

View 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-----

View 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']);
}
?>

View 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;
}
?>

File diff suppressed because it is too large Load Diff

View 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();
}
}

View 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;
}
}