Projet/Mission4/roles/glpi/files/fusioninventory/inc/communication.class.php
2022-02-11 15:48:06 +01:00

491 lines
15 KiB
PHP

<?php
/**
* FusionInventory
*
* Copyright (C) 2010-2016 by the FusionInventory Development Team.
*
* http://www.fusioninventory.org/
* https://github.com/fusioninventory/fusioninventory-for-glpi
* http://forge.fusioninventory.org/
*
* ------------------------------------------------------------------------
*
* LICENSE
*
* This file is part of FusionInventory project.
*
* FusionInventory is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FusionInventory is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with FusionInventory. If not, see <http://www.gnu.org/licenses/>.
*
* ------------------------------------------------------------------------
*
* This file is used to manage the communication between the plugin and the
* agents.
*
* ------------------------------------------------------------------------
*
* @package FusionInventory
* @author Vincent Mazzoni
* @author David Durieux
* @copyright Copyright (c) 2010-2016 FusionInventory team
* @license AGPL License 3.0 or (at your option) any later version
* http://www.gnu.org/licenses/agpl-3.0-standalone.html
* @link http://www.fusioninventory.org/
* @link https://github.com/fusioninventory/fusioninventory-for-glpi
*
*/
if (!defined('GLPI_ROOT')) {
die("Sorry. You can't access directly to this file");
}
/**
* Manage communication with agents using XML
*/
class PluginFusioninventoryCommunication {
/**
* Define message variable
*
* @var SimpleXMLElement
*/
protected $message;
/**
* __contruct function used to initialize protected message variable
*/
function __construct() {
$this->message = new SimpleXMLElement(
"<?xml version='1.0' encoding='UTF-8'?><REPLY></REPLY>"
);
PluginFusioninventoryToolbox::logIfExtradebug(
'pluginFusioninventory-communication',
'New PluginFusioninventoryCommunication object.'
);
}
/**
* Get readable XML message (add carriage returns)
*
* @return object SimpleXMLElement
*/
function getMessage() {
return $this->message;
}
/**
* Set XML message
*
* @param string $message XML in string format
*/
function setMessage($message) {
// avoid xml warnings
$this->message = @simplexml_load_string(
$message, 'SimpleXMLElement',
LIBXML_NOCDATA
);
}
/**
* Send response to agent, using given compression algorithm
*
* @param string $compressmode compressed mode: none|zlib|deflate|gzip
*/
function sendMessage($compressmode = 'none') {
if (!$this->message) {
return;
}
switch ($compressmode) {
case 'none':
header("Content-Type: application/xml");
echo PluginFusioninventoryToolbox::formatXML($this->message);
break;
case 'zlib':
// rfc 1950
header("Content-Type: application/x-compress-zlib");
echo gzcompress(
PluginFusioninventoryToolbox::formatXML($this->message)
);
break;
case 'deflate':
// rfc 1951
header("Content-Type: application/x-compress-deflate");
echo gzdeflate(
PluginFusioninventoryToolbox::formatXML($this->message)
);
break;
case 'gzip':
// rfc 1952
header("Content-Type: application/x-compress-gzip");
echo gzencode(
PluginFusioninventoryToolbox::formatXML($this->message)
);
break;
}
}
/**
* If extra-debug is active, write log
*
* @param string $p_logs log message to write
*/
static function addLog($p_logs) {
if ($_SESSION['glpi_use_mode']==Session::DEBUG_MODE) {
if (PluginFusioninventoryConfig::isExtradebugActive()) {
file_put_contents(GLPI_LOG_DIR.'/pluginFusioninventory-communication.log',
"\n".time().' : '.$p_logs,
FILE_APPEND);
}
}
}
/**
* Import and parse the XML sent by the agent
*
* @param object $arrayinventory SimpleXMLElement
* @return boolean
*/
function import($arrayinventory) {
$pfAgent = new PluginFusioninventoryAgent();
PluginFusioninventoryToolbox::logIfExtradebug(
'pluginFusioninventory-communication',
'Function import().'
);
$this->message = $arrayinventory;
$errors = '';
$xmltag = $this->message['QUERY'];
if ($xmltag == "NETDISCOVERY") {
$xmltag = "NETWORKDISCOVERY";
}
if ($xmltag == "SNMPQUERY"
OR $xmltag == "SNMPINVENTORY") {
$xmltag = "NETWORKINVENTORY";
}
if (!isset($_SESSION['plugin_fusioninventory_agents_id'])) {
$agent = $pfAgent->infoByKey($this->message['DEVICEID']);
} else {
$agent = ['id' => $_SESSION['plugin_fusioninventory_agents_id']];
}
if ($xmltag == "PROLOG") {
return false;
}
if (isset($this->message['CONTENT']['MODULEVERSION'])) {
$pfAgent->setAgentVersions($agent['id'],
$xmltag,
$this->message['CONTENT']['MODULEVERSION']);
} else if (isset($this->message['CONTENT']['VERSIONCLIENT'])) {
$version = str_replace("FusionInventory-Agent_",
"",
$this->message['CONTENT']['VERSIONCLIENT']);
$pfAgent->setAgentVersions($agent['id'], $xmltag, $version);
}
if (isset($this->message->CONTENT->MODULEVERSION)) {
$pfAgent->setAgentVersions($agent['id'],
$xmltag,
(string)$this->message->CONTENT->MODULEVERSION);
} else if (isset($this->message->CONTENT->VERSIONCLIENT)) {
$version = str_replace("FusionInventory-Agent_",
"",
(string)$this->message->CONTENT->VERSIONCLIENT);
$pfAgent->setAgentVersions($agent['id'], $xmltag, $version);
}
if (isset($_SESSION['glpi_plugin_fusioninventory']['xmltags']["$xmltag"])) {
$moduleClass = $_SESSION['glpi_plugin_fusioninventory']['xmltags']["$xmltag"];
$moduleCommunication = new $moduleClass();
$errors.=$moduleCommunication->import($this->message['DEVICEID'],
$this->message['CONTENT'],
$arrayinventory);
} else {
$errors.=__('Unattended element in', 'fusioninventory').' QUERY : *'.$xmltag."*\n";
}
$result=true;
// TODO manage this error ( = delete it)
if ($errors != '') {
echo $errors;
if (isset($_SESSION['glpi_plugin_fusioninventory_processnumber'])) {
$result=true;
} else {
// It's PROLOG
$result=false;
}
}
return $result;
}
/**
* Get all tasks prepared for the agent
*
* @param integer $agent_id id of the agent
*/
function getTaskAgent($agent_id) {
$pfTask = new PluginFusioninventoryTask();
/**
* TODO: the following must be definitely done differently !
* (... but i'm kind in a hurry right now ;-) )
*/
$methods = [];
$classnames = [];
foreach (PluginFusioninventoryStaticmisc::getmethods() as $method) {
if (isset($method['classname'])) {
$methods[] = $method['method'];
$classnames[$method['method']] = $method['classname'];
}
}
$jobstates = $pfTask->getTaskjobstatesForAgent($agent_id, $methods);
foreach ($jobstates as $jobstate) {
$className = $classnames[$jobstate->method];
if (class_exists($className)) {
/*
* TODO: check if use_rest is enabled in Staticmisc::get_methods.
* Also, this get_methods function need to be reviewed
*/
if ($className != "PluginFusioninventoryInventoryComputerESX"
&& $className != "PluginFusioninventoryDeployCommon"
&& $className != "PluginFusioninventoryCollect") {
$class = new $className();
$sxml_temp = $class->run($jobstate);
PluginFusioninventoryToolbox::appendSimplexml(
$this->message, $sxml_temp
);
}
}
}
}
/**
* Set prolog for agent
*/
function addProlog() {
$pfConfig = new PluginFusioninventoryConfig();
$this->message->addChild('PROLOG_FREQ', $pfConfig->getValue("inventory_frequence"));
}
/**
* Order to agent to do inventory if module inventory is activated for the
* agent
*
* @param integer $agents_id id of the agent
*/
function addInventory($agents_id) {
$pfAgentmodule = new PluginFusioninventoryAgentmodule();
if ($pfAgentmodule->isAgentCanDo('INVENTORY', $agents_id)) {
$this->message->addChild('RESPONSE', "SEND");
}
}
/**
* Manage communication with old protocol (XML over POST)
*
**/
/**
* Manage communication with old protocol (XML over POST).
* Used for inventory, network discovery, network inventory and wake on lan
*
* @param string $rawdata data get from agent (compressed or not)
* @param string $xml
* @param string $output
*/
function handleOCSCommunication($rawdata, $xml = '', $output = 'ext') {
// ***** For debug only ***** //
//$rawdata = gzcompress('');
// ********** End ********** //
$config = new PluginFusioninventoryConfig();
$user = new User();
if (!isset($_SESSION['glpiID'])) {
$users_id = $config->getValue('users_id');
$_SESSION['glpiID'] = $users_id;
$user->getFromDB($users_id);
Session::changeActiveEntities();
$_SESSION["glpiname"] = $user->getField('name');
$_SESSION['glpiactiveprofile'] = [];
$_SESSION['glpiactiveprofile']['interface'] = 'central';
$_SESSION['glpiactiveprofile']['internet'] = ALLSTANDARDRIGHT;
$_SESSION['glpiactiveprofile']['computer'] = ALLSTANDARDRIGHT;
$_SESSION['glpiactiveprofile']['monitor'] = ALLSTANDARDRIGHT;
$_SESSION['glpiactiveprofile']['printer'] = ALLSTANDARDRIGHT;
$_SESSION['glpiactiveprofile']['peripheral'] = ALLSTANDARDRIGHT;
$_SESSION['glpiactiveprofile']['networking'] = ALLSTANDARDRIGHT;
$_SESSION["glpi_plugin_fusioninventory_profile"]['unmanaged'] = ALLSTANDARDRIGHT;
}
$communication = new PluginFusioninventoryCommunication();
$pfToolbox = new PluginFusioninventoryToolbox();
// identify message compression algorithm
PluginFusioninventoryDisplay::disableDebug();
$compressmode = '';
$content_type = filter_input(INPUT_SERVER, "CONTENT_TYPE");
if (!empty($xml)) {
$compressmode = 'none';
} else if ($content_type == "application/x-compress-zlib") {
$xml = gzuncompress($rawdata);
$compressmode = "zlib";
} else if ($content_type == "application/x-compress-gzip") {
$xml = $pfToolbox->gzdecode($rawdata);
$compressmode = "gzip";
} else if ($content_type == "application/xml") {
$xml = $rawdata;
$compressmode = 'none';
} else {
// try each algorithm successively
if (($xml = gzuncompress($rawdata))) {
$compressmode = "zlib";
} else if (($xml = $pfToolbox->gzdecode($rawdata))) {
$compressmode = "gzip";
} else if (($xml = gzinflate (substr($rawdata, 2)))) {
// accept deflate for OCS agent 2.0 compatibility,
// but use zlib for answer
if (strstr($xml, "<QUERY>PROLOG</QUERY>")
AND !strstr($xml, "<TOKEN>")) {
$compressmode = "zlib";
} else {
$compressmode = "deflate";
}
} else {
$xml = $rawdata;
$compressmode = 'none';
}
}
PluginFusioninventoryDisplay::reenableusemode();
// check if we are in ssl only mode
$ssl = $config->getValue('ssl_only');
if ($ssl == "1" AND filter_input(INPUT_SERVER, "HTTPS") != "on") {
if ($output == 'glpi') {
Session::addMessageAfterRedirect('SSL REQUIRED BY SERVER', false, ERROR);
} else {
$communication->setMessage("<?xml version='1.0' encoding='UTF-8'?>
<REPLY>
<ERROR>SSL REQUIRED BY SERVER</ERROR>
</REPLY>");
$communication->sendMessage($compressmode);
}
return;
}
PluginFusioninventoryConfig::logIfExtradebug(
'pluginFusioninventory-dial' . uniqid(),
$xml
);
// Check XML integrity
$pxml = @simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
if (!$pxml) {
$pxml = @simplexml_load_string(
utf8_encode($xml),
'SimpleXMLElement',
LIBXML_NOCDATA
);
if ($pxml) {
$xml = utf8_encode($xml);
}
}
if (!$pxml) {
$xml = preg_replace ('/<FOLDER>.*?<\/SOURCE>/', '', $xml);
$pxml = @simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
if (!$pxml) {
if ($output == 'glpi') {
Session::addMessageAfterRedirect('XML not well formed!', false, ERROR);
} else {
$communication->setMessage("<?xml version='1.0' encoding='UTF-8'?>
<REPLY>
<ERROR>XML not well formed!</ERROR>
</REPLY>");
$communication->sendMessage($compressmode);
}
return;
}
}
$_SESSION['plugin_fusioninventory_compressmode'] = $compressmode;
// Convert XML into PHP array
$arrayinventory = PluginFusioninventoryFormatconvert::XMLtoArray($pxml);
unset($pxml);
$deviceid = '';
if (isset($arrayinventory['DEVICEID'])) {
$deviceid = $arrayinventory['DEVICEID'];
}
$agent = new PluginFusioninventoryAgent();
$agents_id = $agent->importToken($arrayinventory);
$_SESSION['plugin_fusioninventory_agents_id'] = $agents_id;
if (!$communication->import($arrayinventory)) {
if ($deviceid != '') {
$communication->setMessage("<?xml version='1.0' encoding='UTF-8'?>
<REPLY>
</REPLY>");
$a_agent = $agent->infoByKey($deviceid);
// Get taskjob in waiting
$communication->getTaskAgent($a_agent['id']);
// ******** Send XML
$communication->addInventory($a_agent['id']);
$communication->addProlog();
$communication->sendMessage($compressmode);
}
} else {
if ($output == 'glpi') {
Session::addMessageAfterRedirect('XML has been imported succesfully!');
} else {
$communication->setMessage("<?xml version='1.0' encoding='UTF-8'?>
<REPLY>
</REPLY>");
$communication->sendMessage($compressmode);
}
}
}
}