2023-06-14 11:09:08 +02:00
< ? php
/**
* Manage ExtensionsDiscovery wizard for Pandora FMS Discovery
*
* @ category Wizard
* @ package Pandora FMS
* @ subpackage ExtensionsDiscovery
* @ version 1.0 . 0
* @ license See below
*
* ______ ___ _______ _______ ________
* | __ \ .-----.--.--.--| |.-----.----.-----. | ___ | | | __ |
* | __ /| _ | | _ || _ | _ | _ | | ___ | | __ |
* | ___ | | ___ . _ | __ | __ | _____ || _____ | __ | | ___ . _ | | ___ | | __ | _ | __ | _______ |
*
* ============================================================================
* Copyright ( c ) 2007 - 2023 Artica Soluciones Tecnologicas , http :// www . artica . es
* This code is NOT free software . This code is NOT licenced under GPL2 licence
* You cannnot redistribute it without written permission of copyright holder .
* ============================================================================
*/
use PandoraFMS\Tools\Files ;
require_once $config [ 'homedir' ] . '/godmode/wizards/Wizard.main.php' ;
/**
* Implements extensionsDiscovery in wizard .
*/
class ExtensionsDiscovery extends Wizard
{
/**
* Id from extension
*
* @ var integer
*/
public $id ;
/**
* Name from extension
*
* @ var string
*/
public $name ;
/**
* Description from extension
*
* @ var string
*/
public $description ;
/**
* Path from extensions Discovery
*
* @ var string
*/
public $path = '/attachment/discovery' ;
/**
* Icon from extensions Discovery
*
* @ var string
*/
public $icon = 'logo.png' ;
/**
* Section Discovery
*
* @ var string
*/
public $section = 'custom' ;
/**
* Extension to load
*
* @ var string
*/
public $mode = null ;
/**
* Last page for steps .
*
* @ var integer
*/
public $lastPage ;
/**
* Url page
*
* @ var string
*/
public $url ;
/**
* All information from ini file extension .
*
* @ var array
*/
public $iniFile ;
/**
* Current page
*
* @ var integer
*/
public $currentPage ;
/**
* Values of macros in database .
*
* @ var array
*/
public $macrosValues = false ;
/**
* Id from task
*
* @ var integer
*/
public $idTask ;
/**
* Name of fields for send .
*
* @ var array
*/
public $nameFields ;
/**
* List of select data custom of pandora
*
* @ var array
*/
public $pandoraSelectData = [
'agent_groups' ,
'agents' ,
'module_groups' ,
'modules' ,
'module_types' ,
'status' ,
'alert_templates' ,
'alert_actions' ,
'interval' ,
'tags' ,
'credentials.custom' ,
'credentials.aws' ,
'credentials.azure' ,
'credentials.sap' ,
'credentials.snmp' ,
'credentials.gcp' ,
'credentials.wmi' ,
'os' ,
];
/**
* Default logo for extension .
*
* @ var string
*/
public $defaultLogo = '/images/wizard/app_generico.svg' ;
/**
* Constructor .
*
* @ param string $_section In discovery .
* @ param string $_mode Extension to load .
*
* @ return mixed
*/
public function __construct ( $_section = 'custom' , $_mode = null )
{
$this -> section = $_section ;
$this -> mode = $_mode ;
$this -> url = 'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=' . $_section ;
$this -> loadConfig ();
}
/**
* Load config from extension .
*
* @ return void
*/
private function loadConfig ()
{
$row = db_get_row ( 'tdiscovery_apps' , 'short_name' , $this -> mode );
$this -> id = $row [ 'id_app' ];
$this -> name = $row [ 'name' ];
$this -> description = $row [ 'description' ];
}
/**
* Return array extensions filtered by section
*
* @ return array Extensions for
*/
public function loadExtensions ()
{
global $config ;
// Check access.
check_login ();
$extensions = [];
$rows = $this -> getExtensionsApps ();
foreach ( $rows as $key => $extension ) {
$logo = $this -> path . '/' . $extension [ 'short_name' ] . '/' . $this -> icon ;
if ( file_exists ( $config [ 'homedir' ] . $logo ) === false ) {
$logo = $this -> defaultLogo ;
}
$extensions [] = [
'icon' => $logo ,
'label' => $extension [ 'name' ],
'url' => ui_get_full_url (
'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz=' . $this -> section . '&mode=' . $extension [ 'short_name' ]
),
];
}
return $extensions ;
}
/**
* Return all extensions from apps section
*
* @ return array extensions .
*/
public function getExtensionsApps ()
{
return db_get_all_rows_filter ( 'tdiscovery_apps' , [ 'section' => $this -> section ]);
}
/**
* Load the extension information from discovery_definition . ini .
*
* @ return array Information ini file .
*/
public function loadIni ()
{
global $config ;
$iniFile = parse_ini_file ( $config [ 'homedir' ] . $this -> path . '/' . $this -> mode . '/discovery_definition.ini' , true , INI_SCANNER_TYPED );
return $iniFile ;
}
/**
* Return next page from config_steps .
*
* @ return integer Return the number of next page .
*/
public function nextPage ()
{
$pages = array_keys ( $this -> iniFile [ 'config_steps' ][ 'name' ]);
if ( $this -> currentPage === 0 || empty ( $this -> currentPage ) === true ) {
return $pages [ 0 ];
}
foreach ( $pages as $k => $page ) {
if ( $page === $this -> currentPage ) {
if ( end ( $pages ) === $this -> currentPage ) {
return $this -> currentPage ;
} else {
return $pages [( $k + 1 )];
}
}
}
}
/**
* Draw the extension forms .
*
* @ return boolean Return boolean if exist error .
*/
public function run ()
{
2023-06-27 17:37:41 +02:00
ui_require_javascript_file ( 'extensions_discovery' );
2023-06-14 11:09:08 +02:00
$_iniFile = $this -> loadIni ();
if ( $_iniFile === false ) {
2023-08-29 10:27:35 +02:00
// No file .disco.
ui_print_info_message ([ 'no_close' => true , 'message' => __ ( 'No .disco file found' ) ]);
2023-06-14 11:09:08 +02:00
return false ;
}
$this -> iniFile = $_iniFile ;
if ( empty ( $this -> iniFile [ 'config_steps' ]) === false ) {
$this -> lastPage = end ( array_keys ( $this -> iniFile [ 'config_steps' ][ 'name' ]));
} else {
$this -> lastPage = 0 ;
}
$this -> currentPage = ( int ) get_parameter ( 'page' , '0' );
$this -> idTask = get_parameter ( 'id_task' , '' );
$action = get_parameter ( 'action' , '' );
$isTheEnd = get_parameter ( 'complete_button' , '' );
// Control parameters and errors.
$error = false ;
if ( $action === 'task_definition_form' ) {
$error = $this -> processTaskDefinition ();
}
if ( $action === 'process_macro' ) {
$error = $this -> processCustomMacro ();
}
$task = $this -> getTask ();
if ( $task === false && $this -> currentPage > 0 ) {
$error = __ ( 'Task not defined' );
}
// Build breadcrum.
$breadcrum = [
[
'link' => 'index.php?sec=gservers&sec2=godmode/servers/discovery' ,
'label' => 'Discovery' ,
],
];
switch ( $this -> section ) {
case 'app' :
$breadcrum [] = [
'link' => $this -> url ,
'label' => __ ( 'Application' ),
];
break ;
case 'cloud' :
$breadcrum [] = [
'link' => $this -> url ,
'label' => __ ( 'Cloud' ),
];
break ;
case 'custom' :
$breadcrum [] = [
'link' => $this -> url ,
'label' => __ ( 'Custom' ),
];
break ;
default :
$breadcrum [] = [
'link' => $this -> url ,
'label' => __ ( 'Custom' ),
];
break ;
}
$parameters = '' ;
if ( empty ( $this -> idTask ) === false ) {
$parameters .= '&id_task=' . $this -> idTask ;
}
$breadcrum [] = [
'link' => $this -> url . '&mode=' . $this -> mode . $parameters ,
'label' => 'Task definition' ,
'selected' => (( 0 === ( int ) $this -> currentPage ) ? 1 : 0 ),
];
foreach ( $this -> iniFile [ 'config_steps' ][ 'name' ] as $key => $step ) {
$parameters = '&mode=' . $this -> mode . '&page=' . $key ;
if ( empty ( $this -> idTask ) === false ) {
$parameters .= '&id_task=' . $this -> idTask ;
}
$breadcrum [] = [
'link' => $this -> url . $parameters ,
'label' => $step ,
'selected' => (( $key === ( int ) $this -> currentPage ) ? 1 : 0 ),
];
}
// Avoid to print header out of wizard.
$this -> prepareBreadcrum ( $breadcrum );
// Header.
ui_print_page_header (
$this -> iniFile [ 'discovery_extension_definition' ][ 'name' ],
'' ,
false ,
'' ,
true ,
'' ,
false ,
'' ,
GENERIC_SIZE_TEXT ,
'' ,
$this -> printHeader ( true )
);
if ( $error !== false ) {
ui_print_error_message (
$error
);
return ;
} else if ( $action !== '' ) {
ui_print_success_message ( __ ( 'Operation realized' ));
if ( empty ( $isTheEnd ) === false ) {
header ( 'Location:' . $config [ 'homeurl' ] . 'index.php?sec=discovery&sec2=godmode/servers/discovery&wiz=tasklist' );
}
}
$_url = ui_get_full_url (
sprintf (
$this -> url . '&mode=%s&page=%s%s' ,
$this -> mode ,
$this -> nextPage (),
( empty ( $this -> idTask ) === false ) ? '&id_task=' . $this -> idTask : '' ,
)
);
$table = new StdClass ();
$table -> id = 'form_editor' ;
$table -> width = '100%' ;
$table -> class = 'databox filter-table-adv max_floating_element_size' ;
$table -> style = [];
$table -> style [ 0 ] = 'width: 50%' ;
$table -> style [ 1 ] = 'width: 50%' ;
$table -> data = [];
if ( $this -> currentPage === 0 ) {
// If page is 0 then create form for task definition.
$table -> data = $this -> viewTaskDefinition ();
} else {
// If page is bigger than 0 then render form .ini.
$table -> data = $this -> viewMacroForm ();
}
echo '<form type="submit" action="' . $_url . '" method="post">' ;
html_print_table ( $table );
$actionButtons = '' ;
if ( $this -> currentPage !== $this -> nextPage ()) {
$actionButtons = html_print_submit_button (
__ ( 'Next' ),
'next_button' ,
false ,
[
'class' => 'sub' ,
'icon' => 'plus' ,
],
true
);
}
$actionButtons .= html_print_submit_button (
__ ( 'Complete setup' ),
'complete_button' ,
false ,
[
'class' => 'sub' ,
'icon' => 'update' ,
'value' => '1' ,
],
true
);
html_print_action_buttons ( $actionButtons );
echo '</form>' ;
}
/**
* Draw a select with the pandora data
*
* @ param string $selectData Type of select .
* @ param string $name Name of select .
* @ param string $defaultValue Default value .
* @ param boolean $multiple Define if the select is multiple .
* @ param boolean $required Define if field is required .
*
* @ return string Return the html select .
*/
private function drawSelectPandora ( $selectData , $name , $defaultValue , $multiple = false , $required = false )
{
if ( $multiple === true && $selectData !== 'interval' ) {
$name .= '[]' ;
$defaultValue = json_decode ( $defaultValue );
} else {
$defaultValue = io_safe_input ( $defaultValue );
}
switch ( $selectData ) {
case 'agent_groups' :
$input = html_print_select_groups (
false ,
'AR' ,
true ,
$name ,
$defaultValue ,
'' ,
'' ,
'' ,
true ,
$multiple ,
false ,
'' ,
false ,
false ,
false ,
false ,
'id_grupo' ,
true ,
false ,
false ,
false ,
false ,
$required
);
break ;
case 'agents' :
$input = html_print_select_from_sql (
'SELECT nombre, alias as n FROM tagente' ,
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
false ,
'width: 100%;' ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
$required
);
break ;
case 'module_groups' :
$input = html_print_select_from_sql (
' SELECT id_mg , name
FROM tmodule_group ORDER BY name ' ,
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
false ,
'width: 100%' ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
$required
);
break ;
case 'modules' :
$input = html_print_select_from_sql (
2023-06-15 09:57:11 +02:00
'select nombre, nombre as n from tagente_modulo' ,
2023-06-14 11:09:08 +02:00
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
false ,
'width: 100%' ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
$required
);
break ;
case 'module_types' :
$input = html_print_select_from_sql (
'select nombre, descripcion from ttipo_modulo' ,
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
false ,
'width: 100%' ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
$required
);
break ;
case 'status' :
$module_status_arr = [];
// Default.
$module_status_arr [ AGENT_MODULE_STATUS_NORMAL ] = __ ( 'Normal' );
$module_status_arr [ AGENT_MODULE_STATUS_WARNING ] = __ ( 'Warning' );
$module_status_arr [ AGENT_MODULE_STATUS_CRITICAL_BAD ] = __ ( 'Critical' );
$module_status_arr [ AGENT_MODULE_STATUS_UNKNOWN ] = __ ( 'Unknown' );
$module_status_arr [ AGENT_MODULE_STATUS_NOT_INIT ] = __ ( 'Not init' );
$input = html_print_select (
$module_status_arr ,
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
'' ,
false ,
'width:100%' ,
false ,
false ,
false ,
'' ,
false ,
false ,
$required ,
false ,
true ,
true
);
break ;
case 'alert_templates' :
$input = html_print_select_from_sql (
'select id, name from talert_templates' ,
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
false ,
'width: 100%' ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
$required
);
break ;
case 'alert_actions' :
$input = html_print_select_from_sql (
'select id, name from talert_actions' ,
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
false ,
'width: 100%' ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
$required
);
break ;
case 'interval' :
$input = html_print_extended_select_for_time (
$name ,
( string ) $defaultValue ,
'' ,
'' ,
'0' ,
false ,
true
);
break ;
case 'tags' :
$input = html_print_select_from_sql (
'select id_tag, name from ttag' ,
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
false ,
'width: 100%' ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
$required
);
break ;
case 'credentials.custom' :
$input = html_print_select_from_sql (
'select identifier, identifier as i from tcredential_store WHERE product = "custom"' ,
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
false ,
'width: 100%' ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
$required
);
break ;
case 'credentials.aws' :
$input = html_print_select_from_sql (
'select identifier, identifier as i from tcredential_store WHERE product = "AWS"' ,
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
false ,
'width: 100%' ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
$required
);
break ;
case 'credentials.azure' :
$input = html_print_select_from_sql (
'select identifier, identifier as i from tcredential_store WHERE product = "AZURE"' ,
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
false ,
'width: 100%' ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
$required
);
break ;
case 'credentials.sap' :
$input = html_print_select_from_sql (
'select identifier, identifier as i from tcredential_store WHERE product = "SAP"' ,
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
false ,
'width: 100%' ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
$required
);
break ;
case 'credentials.snmp' :
$input = html_print_select_from_sql (
'select identifier, identifier as i from tcredential_store WHERE product = "SNMP"' ,
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
false ,
'width: 100%' ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
$required
);
break ;
case 'credentials.gcp' :
$input = html_print_select_from_sql (
'select identifier, identifier as i from tcredential_store WHERE product = "GOOGLE"' ,
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
false ,
'width: 100%' ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
$required
);
break ;
case 'credentials.wmi' :
$input = html_print_select_from_sql (
'select identifier, identifier as i from tcredential_store WHERE product = "WMI"' ,
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
false ,
'width: 100%' ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
$required
);
break ;
case 'os' :
$input = html_print_select_from_sql (
'SELECT id_os, name FROM tconfig_os ORDER BY name' ,
$name ,
$defaultValue ,
'' ,
( $multiple === false ) ? __ ( 'None selected' ) : '' ,
'' ,
true ,
$multiple ,
true ,
false ,
'width: 100%' ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
$required
);
break ;
default :
$input = html_print_select (
[],
$name ,
$defaultValue ,
'' ,
'' ,
0 ,
true
);
break ;
}
return $input ;
}
/**
* Draw input from parameters of . ini .
*
* @ param array $parameters Configuration of input .
* @ param boolean $implicit Indicates if all the configuration is indicated in the array .
*
* @ return string Html from input .
*/
public function drawInput ( $parameters , $implicit = false )
{
$input = '' ;
$defaultValue = $this -> macrosValues [ $parameters [ 'macro' ]];
switch ( $parameters [ 'type' ]) {
case 'string' :
$input = html_print_input_text (
$parameters [ 'macro' ],
$defaultValue ,
'' ,
50 ,
255 ,
true ,
false ,
( $parameters [ 'mandatory_field' ] === false ) ? false : true
);
break ;
case 'number' :
$config = [
'type' => 'number' ,
'name' => $parameters [ 'macro' ],
'value' => $defaultValue ,
'return' => true ,
];
if ( $parameters [ 'mandatory_field' ] !== false ) {
$config [ 'required' ] = true ;
}
$input = html_print_input ( $config );
break ;
case 'password' :
$isEncrypted = ( bool ) $this -> macrosValues [ $parameters [ 'encrypt_on_true' ]];
if ( $isEncrypted === true ) {
$defaultValueEncrypted = $this -> encryptPassword ( $defaultValue , true );
if ( empty ( $defaultValueEncrypted ) === false ) {
$defaultValue = $defaultValueEncrypted ;
}
}
$input = html_print_input_password (
$parameters [ 'macro' ],
$defaultValue ,
'' ,
50 ,
255 ,
true ,
false ,
( $parameters [ 'mandatory_field' ] === false ) ? false : true ,
'' ,
'on'
);
if ( empty ( $parameters [ 'encrypt_on_true' ]) === false ) {
$input .= html_print_input_hidden (
$parameters [ 'macro' ] . '_encrypt' ,
$parameters [ 'encrypt_on_true' ],
true
);
}
break ;
case 'checkbox' :
$input = html_print_checkbox_switch (
$parameters [ 'macro' ],
1 ,
( bool ) $defaultValue ,
true
);
break ;
case 'textarea' :
$input = html_print_textarea (
$parameters [ 'macro' ],
5 ,
20 ,
$defaultValue ,
( $parameters [ 'mandatory_field' ] === false ) ? '' : 'required="required"' ,
true
);
break ;
case 'select' :
if ( in_array ( $parameters [ 'select_data' ], $this -> pandoraSelectData ) === true ) {
$input = $this -> drawSelectPandora (
$parameters [ 'select_data' ],
$parameters [ 'macro' ],
$defaultValue ,
false ,
( $parameters [ 'mandatory_field' ] === false ) ? false : true ,
);
$parameters [ 'type' ] = $parameters [ 'select_data' ];
} else {
if ( $implicit === false ) {
$options = $this -> iniFile [ $parameters [ 'select_data' ]][ 'option' ];
} else {
$options = $parameters [ 'select_data' ];
}
$input = html_print_select (
$options ,
$parameters [ 'macro' ],
$defaultValue ,
'' ,
__ ( 'None selected' ),
'' ,
true ,
false ,
true ,
'' ,
false ,
'width: 100%;' ,
false ,
false ,
false ,
'' ,
false ,
false ,
( $parameters [ 'mandatory_field' ] === false ) ? false : true ,
);
}
break ;
case 'multiselect' :
if ( in_array ( $parameters [ 'select_data' ], $this -> pandoraSelectData ) === true ) {
$input = $this -> drawSelectPandora (
$parameters [ 'select_data' ],
$parameters [ 'macro' ],
$defaultValue ,
true ,
);
$parameters [ 'type' ] = $parameters [ 'select_data' ];
} else {
if ( $implicit === false ) {
$options = $this -> iniFile [ $parameters [ 'select_data' ]][ 'option' ];
} else {
$options = $parameters [ 'select_data' ];
}
$input = html_print_select (
$options ,
$parameters [ 'macro' ] . '[]' ,
json_decode ( $defaultValue , true ),
'' ,
'' ,
0 ,
true ,
true ,
true ,
'' ,
false ,
'width: 100%' ,
false ,
false ,
false ,
'' ,
false ,
false ,
false ,
false ,
true ,
true
);
}
break ;
case 'tree' :
// Show bucket tree explorer.
ui_require_javascript_file ( 'pandora_snmp_browser' );
if ( $implicit === false ) {
$treeData = $this -> iniFile [ $parameters [ 'tree_data' ]];
$treeInfo = $this -> getTreeStructure ( $parameters , $treeData );
} else {
$treeData = $parameters [ 'tree_data' ];
$treeInfo = $this -> getTreeStructureByScript ( $parameters , $treeData );
}
$input = ui_print_tree (
$treeInfo ,
// Id.
0 ,
// Depth.
0 ,
// Last.
0 ,
// Last_array.
[],
// Sufix.
true ,
// Return.
true ,
// Descriptive ids.
false
);
break ;
default :
$input = html_print_input_text (
$parameters [ 'macro' ],
$defaultValue ,
'' ,
50 ,
255 ,
true ,
false ,
( $parameters [ 'mandatory_field' ] === false ) ? false : true
);
break ;
}
$input .= html_print_input_hidden (
$parameters [ 'macro' ] . 'type' ,
$parameters [ 'type' ],
true
);
$class = '' ;
if ( $parameters [ 'show_on_true' ] !== null ) {
$class = $parameters [ 'macro' ] . '_hide' ;
$input .= $this -> showOnTrue ( $parameters [ 'show_on_true' ], $class );
}
$name = $parameters [ 'name' ];
if ( empty ( $parameters [ 'tip' ]) === false ) {
$name .= ui_print_help_tip ( $parameters [ 'tip' ], true );
}
return html_print_label_input_block (
$name ,
$input ,
[ 'div_class' => $class ]
);
}
/**
* Return the task app from database .
*
* @ return array $task Task of database .
*/
private function getTask ()
{
return db_get_row_filter (
'trecon_task' ,
[
'id_app' => $this -> id ,
'id_rt' => $this -> idTask ,
'type' => 15 ,
],
);
}
/**
* Returns the value of the macro .
*
* @ param string $macro Name of macro for filter .
*
* @ return mixed Value of the macro .
*/
private function getValueMacro ( $macro )
{
return db_get_value_filter (
'value' ,
'tdiscovery_apps_tasks_macros' ,
[
'id_task' => $this -> idTask ,
'macro' => $macro ,
]
);
}
/**
* Return form for macro form .
*
* @ return array $form Form macro .
*/
private function viewMacroForm ()
{
$data = [];
$macros = db_get_all_rows_filter (
'tdiscovery_apps_tasks_macros' ,
[ 'id_task' => $this -> idTask ],
[ '*' ]
);
if ( $macros !== false ) {
foreach ( $macros as $key => $macro ) {
$this -> macrosValues [ $macro [ 'macro' ]] = io_safe_output ( $macro [ 'value' ]);
}
}
// Process ini or script.
$customFields = $this -> iniFile [ 'config_steps' ][ 'custom_fields' ][ $this -> currentPage ];
$customFieldsByScript = $this -> getStructureFormByScript ( $this -> iniFile [ 'config_steps' ][ 'script_data_fields' ][ $this -> currentPage ]);
if ( $customFields === null && $customFieldsByScript === null ) {
$data [ 0 ][ 0 ] = html_print_image (
'images/no_data_toshow.png' ,
true ,
[ 'class' => 'w200px' ]
);
$data [ 1 ][ 0 ] = html_print_input_hidden (
'action' ,
'process_macro' ,
true
);
return $data ;
}
$columns = 2 ;
if ( $this -> iniFile [ 'config_steps' ][ 'fields_columns' ][ $this -> currentPage ] !== null
&& $this -> iniFile [ 'config_steps' ][ 'fields_columns' ][ $this -> currentPage ] === 1
) {
$columns = 1 ;
}
$row = 0 ;
$col = 0 ;
foreach ( $customFieldsByScript as $key => $value ) {
$this -> nameFields [] = $value [ 'macro' ];
$data [ $row ][ $col ] = $this -> drawInput ( $value , true );
$col ++ ;
if ( $col == $columns ) {
$row ++ ;
$col = 0 ;
}
}
foreach ( $this -> iniFile [ $customFields ][ 'macro' ] as $key => $id ) {
$parameters = [
'macro' => $id ,
'name' => $this -> iniFile [ $customFields ][ 'name' ][ $key ],
'tip' => $this -> iniFile [ $customFields ][ 'tip' ][ $key ],
'type' => $this -> iniFile [ $customFields ][ 'type' ][ $key ],
'placeholder' => $this -> iniFile [ $customFields ][ 'placeholder' ][ $key ],
'mandatory_field' => $this -> iniFile [ $customFields ][ 'mandatory_field' ][ $key ],
'show_on_true' => $this -> iniFile [ $customFields ][ 'show_on_true' ][ $key ],
'encrypt_on_true' => $this -> iniFile [ $customFields ][ 'encrypt_on_true' ][ $key ],
'select_data' => $this -> iniFile [ $customFields ][ 'select_data' ][ $key ],
'tree_data' => $this -> iniFile [ $customFields ][ 'tree_data' ][ $key ],
];
$this -> nameFields [] = $id ;
$data [ $row ][ $col ] = $this -> drawInput ( $parameters );
$col ++ ;
if ( $col == $columns ) {
$row ++ ;
$col = 0 ;
}
}
$data [( $row + 1 )][ 1 ] = html_print_input_hidden (
'action' ,
'process_macro' ,
true
);
$data [( $row + 1 )][ 1 ] .= html_print_input_hidden (
'name_fields' ,
implode ( ',' , $this -> nameFields ),
true
);
return $data ;
}
/**
* Return form for task definition .
*
* @ return array $form Form for task definition .
*/
private function viewTaskDefinition ()
{
$task = $this -> getTask ();
$data = [];
$data [ 0 ][ 0 ] = html_print_label_input_block (
__ ( 'Task name' ),
html_print_input_text (
'task_name' ,
$task [ 'name' ],
'' ,
50 ,
255 ,
true ,
false ,
true
)
);
$data [ 1 ][ 0 ] = html_print_label_input_block (
__ ( 'Description' ),
html_print_textarea (
'description' ,
5 ,
20 ,
$task [ 'description' ],
'' ,
true
)
);
$data [ 2 ][ 0 ] = html_print_label_input_block (
__ ( 'Discovery server' ),
html_print_select_from_sql (
sprintf (
' SELECT id_server , name
FROM tserver
WHERE server_type = % d
ORDER BY name ' ,
SERVER_TYPE_DISCOVERY
),
'discovery_server' ,
$task [ 'id_recon_server' ],
'' ,
'' ,
'0' ,
true ,
false ,
true ,
false ,
false ,
false ,
GENERIC_SIZE_TEXT ,
'' ,
false
)
);
$data [ 3 ][ 0 ] = html_print_label_input_block (
__ ( 'Group' ),
html_print_select_groups (
false ,
'AR' ,
false ,
'group' ,
$task [ 'id_group' ],
'' ,
'' ,
0 ,
true ,
false ,
false ,
'' ,
false ,
false ,
false ,
false ,
'id_grupo' ,
false ,
false ,
false ,
false ,
false ,
true
)
);
2023-06-27 17:37:41 +02:00
$inputs_interval = html_print_select (
[
'defined' => 'Defined' ,
'manual' => 'Manual' ,
],
'mode_interval' ,
( $task [ 'interval_sweep' ] === '0' ) ? 'manual' : 'defined' ,
'changeModeInterval(this)' ,
'' ,
'0' ,
true ,
false ,
true ,
'' ,
false
) . html_print_extended_select_for_time (
'interval' ,
( empty ( $task [ 'interval_sweep' ]) === true ) ? '300' : $task [ 'interval_sweep' ],
'' ,
'' ,
'0' ,
false ,
true ,
false ,
true ,
);
$js_variables = '<script>const interval = "' . $task [ 'interval_sweep' ] . '";</script>' ;
2023-06-14 11:09:08 +02:00
$data [ 4 ][ 0 ] = html_print_label_input_block (
__ ( 'Interval' ),
2023-06-27 17:37:41 +02:00
html_print_div (
[
'style' => 'display: flex;max-width: 345px; justify-content: space-between;' ,
'content' => $inputs_interval . $js_variables ,
],
2023-06-14 11:09:08 +02:00
true
)
);
$data [ 5 ][ 0 ] = html_print_label_input_block (
__ ( 'Timeout' ) . ui_print_help_tip ( 'This timeout will be applied for each task execution' , true ),
html_print_extended_select_for_time (
'tiemout' ,
( empty ( $task [ 'executions_timeout' ]) === true ) ? '60' : $task [ 'executions_timeout' ],
'' ,
'' ,
'0' ,
false ,
true
),
);
$data [ 6 ][ 0 ] = html_print_input_hidden (
'action' ,
'task_definition_form' ,
true
);
$data [ 7 ][ 0 ] = html_print_input_hidden (
'id_task' ,
$task [ 'id_rt' ],
true
);
return $data ;
}
/**
* Sabe data from task definition form .
*
* @ return string $error Error string if exist .
*/
private function processTaskDefinition ()
{
$taskName = get_parameter ( 'task_name' , '' );
$description = get_parameter ( 'description' , '' );
$discoveryServer = get_parameter ( 'discovery_server' , '' );
$group = get_parameter ( 'group' , 0 );
2023-06-27 17:37:41 +02:00
$mode_interval = get_parameter ( 'mode_interval' , 'defined' );
2023-06-14 11:09:08 +02:00
$interval = get_parameter ( 'interval' , '' );
$tiemout = get_parameter ( 'tiemout' , 60 );
$completeTask = get_parameter ( 'complete_button' , '' );
2023-06-27 17:37:41 +02:00
if ( $mode_interval === 'manual' ) {
$interval = '0' ;
}
2023-06-14 11:09:08 +02:00
$error = false ;
if ( $taskName === ''
|| $discoveryServer === ''
|| $group === ''
|| $interval === ''
) {
$error = __ ( 'Fields empties' );
return $error ;
}
if ( $this -> idTask === '' ) {
db_process_sql_begin ();
try {
$_idTask = db_process_sql_insert (
'trecon_task' ,
[
'id_app' => $this -> id ,
'name' => $taskName ,
'description' => $description ,
'id_group' => $group ,
'interval_sweep' => $interval ,
'id_recon_server' => $discoveryServer ,
'type' => 15 ,
'setup_complete' => ( empty ( $completeTask ) === false ) ? 1 : 0 ,
'executions_timeout' => $tiemout ,
]
);
if ( $_idTask === false ) {
$error = __ ( 'Error creating the discovery task' );
} else {
$this -> idTask = $_idTask ;
$this -> autoLoadConfigMacro ();
}
} catch ( Exception $e ) {
$error = __ ( 'Error creating the discovery task' );
}
if ( $error === false ) {
db_process_sql_commit ();
} else {
db_process_sql_rollback ();
}
} else {
$result = db_process_sql_update (
'trecon_task' ,
[
'id_app' => $this -> id ,
'name' => $taskName ,
'description' => $description ,
'id_group' => $group ,
'interval_sweep' => $interval ,
'id_recon_server' => $discoveryServer ,
'type' => 15 ,
'setup_complete' => ( empty ( $completeTask ) === false ) ? 1 : 0 ,
'executions_timeout' => $tiemout ,
],
[ 'id_rt' => $this -> idTask ]
);
if ( $result === false ) {
$error = __ ( 'Error updating the discovery task' );
}
}
return $error ;
}
/**
* Process the values of input from macro defined in . ini
*
* @ return string $error Error string if exist .
*/
private function processCustomMacro ()
{
$error = false ;
$keyParameters = explode ( ',' , get_parameter ( 'name_fields' , '' ));
foreach ( $keyParameters as $v => $key ) {
$type = get_parameter ( $key . 'type' , '' );
switch ( $type ) {
case 'checkbox' :
$value = get_parameter_switch ( $key , 0 );
break ;
case 'multiselect' :
$value = io_safe_input ( json_encode ( get_parameter ( $key , '' )));
break ;
case 'password' :
$value = get_parameter ( $key , '' );
$encryptKey = get_parameter ( $key . '_encrypt' , '' );
if ( $encryptKey !== '' ) {
$encrypt = ( bool ) get_parameter_switch ( $encryptKey , 0 );
if ( $encrypt === true ) {
$valueEncrypt = $this -> encryptPassword ( $value );
if ( empty ( $valueEncrypt ) === false ) {
$value = $valueEncrypt ;
}
}
}
break ;
default :
$value = get_parameter ( $key , '' );
break ;
}
if ( is_array ( $value ) === true ) {
$value = io_safe_input ( json_encode ( $value ));
}
$exist = db_get_row_filter (
'tdiscovery_apps_tasks_macros' ,
[
'id_task' => $this -> idTask ,
'macro' => $key ,
]
);
if ( in_array ( $type , $this -> pandoraSelectData ) === false ) {
$type = 'custom' ;
}
if ( $exist === false ) {
$result = db_process_sql_insert (
'tdiscovery_apps_tasks_macros' ,
[
'id_task' => $this -> idTask ,
'macro' => $key ,
'value' => $value ,
'type' => $type ,
]
);
if ( $result === false ) {
$error = __ ( 'Field %s not insert' , $key );
}
} else {
$result = db_process_sql_update (
'tdiscovery_apps_tasks_macros' ,
[
'value' => $value ,
'type' => $type ,
],
[
'id_task' => $this -> idTask ,
'macro' => $key ,
]
);
if ( $result === false ) {
$error = __ ( 'Field %s not updated' , $key );
}
}
}
$completeTask = get_parameter ( 'complete_button' , '' );
if ( empty ( $completeTask ) === false ) {
$result = db_process_sql_update (
'trecon_task' ,
[ 'setup_complete' => 1 ],
[ 'id_rt' => $this -> idTask ]
);
if ( $result === false ) {
$error = __ ( 'Task not updated' );
}
}
return $error ;
}
/**
* Check if name of input macro is correct .
*
* @ param string $name Name of input .
*
* @ return boolean value true if name is correct .
*/
private function isCorrectNameInput ( $name )
{
if ( substr ( $name , 0 , 1 ) === '_' && substr ( $name , - 1 ) === '_' ) {
return true ;
} else {
return false ;
}
}
/**
* Return logic for component show on true .
*
* @ param string $checkbox Name the checkbox for hide input .
* @ param string $elementToHide Name the element to hide HIS PARENT .
*
* @ return string String Name the element
*/
private function showOnTrue ( $checkbox , $elementToHide )
{
return ' < script >
$ ( document ) . ready ( function (){
if ( $ ( " [name='. $checkbox .'] " ) . length > 0 ){
if ( ! $ ( " [name='. $checkbox .'] " )[ 0 ] . checked ) {
$ ( " .'. $elementToHide .' " ) . hide ();
}
$ ( " [name='. $checkbox .'] " ) . on ( " change " ,
function ( e ) {
if ( e . currentTarget . checked ) {
$ ( " .'. $elementToHide .' " ) . show ();
} else {
$ ( " .'. $elementToHide .' " ) . hide ();
}
});
}
})
</ script > ' ;
}
/**
* Load the macros task in database
*
* @ throws Exception Excepcion to control possible error for default value .
*
* @ return void
*/
private function autoLoadConfigMacro ()
{
$defaultValues = $this -> iniFile [ 'discovery_extension_definition' ][ 'default_value' ];
foreach ( $defaultValues as $key => $value ) {
if ( $value === false ) {
$value = 0 ;
}
$result = db_process_sql_insert (
'tdiscovery_apps_tasks_macros' ,
[
'id_task' => $this -> idTask ,
'macro' => $key ,
'value' => ( string ) io_safe_input ( $value ),
'type' => 'custom' ,
]
);
if ( $result === false ) {
throw new Exception ( 'Error creating task' );
}
}
$tempFiles = $this -> iniFile [ 'tempfile_confs' ][ 'file' ];
foreach ( $tempFiles as $key => $value ) {
$result = db_process_sql_insert (
'tdiscovery_apps_tasks_macros' ,
[
'id_task' => $this -> idTask ,
'macro' => $key ,
'value' => ( string ) io_safe_input ( $value ),
'type' => 'custom' ,
'temp_conf' => 1 ,
]
);
if ( $result === false ) {
throw new Exception ( 'Error creating task' );
}
}
}
/**
* Return array structure for draw tree when array is by . ini .
*
* @ param array $parent Parent from the tree .
* @ param array $firstChildren First children from parent .
*
* @ return array $treeInfo Return the array with format for render treee
*/
private function getTreeStructure ( $parent , $firstChildren )
{
$treeInfo = [];
foreach ( $firstChildren [ 'name' ] as $key => $value ) {
$checked = false ;
$name = ( empty ( $firstChildren [ 'macro' ][ $key ]) === false ) ? $firstChildren [ 'macro' ][ $key ] . '[]' : $parent [ 'id' ] . '[]' ;
$nameField = ( empty ( $firstChildren [ 'macro' ][ $key ]) === false ) ? $firstChildren [ 'macro' ][ $key ] : $parent [ 'id' ];
if ( in_array ( $nameField , $this -> nameFields ) === false ) {
$this -> nameFields [] = $nameField ;
}
$checkedValues = json_decode ( io_safe_output ( $this -> macrosValues [ $nameField ]), true );
if ( empty ( $checkedValues ) === false ) {
if ( in_array ( $firstChildren [ 'value' ][ $key ], $checkedValues )) {
$checked = true ;
}
}
$treeInfo [ '__LEAVES__' ][ $key ] = [
'label' => $value ,
'selectable' => ( bool ) $firstChildren [ 'selectable' ][ $key ],
'name' => $name ,
'value' => $firstChildren [ 'value' ][ $key ],
'checked' => $checked ,
];
if ( empty ( $firstChildren [ 'children' ][ $key ]) === false ) {
$children = $this -> iniFile [ $firstChildren [ 'children' ][ $key ]];
$treeInfo [ '__LEAVES__' ][ $key ][ 'sublevel' ] = $this -> getTreeStructure ( $parent , $children );
}
}
return $treeInfo ;
}
/**
* Return array structure for draw tree when array is by script .
*
* @ param array $parent Parent from the tree .
* @ param array $firstChildren First children from parent .
*
* @ return array $treeInfo Return the array with format for render treee
*/
private function getTreeStructureByScript ( $parent , $firstChildren )
{
$treeInfo = [];
foreach ( $firstChildren as $key => $value ) {
$checked = false ;
$name = ( empty ( $value [ 'macro' ]) === false ) ? $value [ 'macro' ] . '[]' : $parent [ 'macro' ] . '[]' ;
$nameField = ( empty ( $value [ 'macro' ]) === false ) ? $value [ 'macro' ] : $parent [ 'macro' ];
if ( in_array ( $nameField , $this -> nameFields ) === false ) {
$this -> nameFields [] = $nameField ;
}
$checkedValues = json_decode ( io_safe_output ( $this -> macrosValues [ $nameField ]), true );
if ( empty ( $checkedValues ) === false ) {
if ( in_array ( $value [ 'value' ], $checkedValues , true ) === true ) {
$checked = true ;
}
}
$treeInfo [ '__LEAVES__' ][ $key ] = [
'label' => $value [ 'name' ],
'selectable' => ( bool ) $value [ 'selectable' ],
'name' => $name ,
'value' => $value [ 'value' ],
'checked' => $checked ,
];
if ( empty ( $value [ 'children' ]) === false ) {
$children = $value [ 'children' ];
$treeInfo [ '__LEAVES__' ][ $key ][ 'sublevel' ] = $this -> getTreeStructureByScript ( $parent , $children );
}
}
return $treeInfo ;
}
/**
* Return a json with the form structure for draw .
*
* @ param mixed $command String .
*
* @ return array Result of command .
*/
private function getStructureFormByScript ( $command )
{
global $config ;
$executionFiles = $this -> iniFile [ 'discovery_extension_definition' ][ 'execution_file' ];
foreach ( $executionFiles as $key => $file ) {
$file = $config [ 'homedir' ] . $this -> path . '/' . $this -> mode . '/' . $file ;
$command = str_replace ( $key , $file , $command );
}
$values = $this -> replaceValues ( $command );
$command = $values [ 'command' ];
$toDelete = $values [ 'delete' ];
if ( empty ( $command ) === false ) {
$result = $this -> executeCommand ( $command );
}
if ( count ( $toDelete ) > 0 ) {
foreach ( $toDelete as $key => $folder ) {
Files :: rmrf ( $folder );
}
}
return json_decode ( $result , true );
}
/**
* Replace values in command
*
* @ param string $command String command for replace macros .
*
* @ return array $values Command and files to delete .
*/
private function replaceValues ( $command )
{
preg_match_all ( '/\b_[a-zA-Z0-9]*_\b/' , $command , $matches );
$foldersToDelete = [];
foreach ( $matches [ 0 ] as $key => $macro ) {
$row = db_get_row_filter (
'tdiscovery_apps_tasks_macros' ,
[
'macro' => $macro ,
'id_task' => $this -> idTask ,
]
);
if ( $row !== false ) {
if ( in_array ( $row [ 'type' ], $this -> pandoraSelectData ) === true ) {
$value = $this -> getValuePandoraSelect ( $row [ 'type' ], $row [ 'value' ]);
$command = str_replace ( $macro , $value , $command );
} else if (( int ) $row [ 'temp_conf' ] === 1 ) {
$nameFile = $row [ 'id_task' ] . '_' . $row [ 'id_task' ] . '_' . uniqid ();
$value = $this -> getValueTempFile ( $nameFile , $row [ 'value' ]);
$command = str_replace ( $macro , $value , $command );
$foldersToDelete [] = str_replace ( $nameFile , '' , $value );
} else {
$command = str_replace ( $macro , io_safe_output ( $row [ 'value' ]), $command );
}
}
}
return [
'command' => $command ,
'delete' => $foldersToDelete ,
];
}
/**
* Create a temp file for tempfile_confs macros .
*
* @ param string $nameFile Name file only .
* @ param string $content Content to save to file .
*
* @ return string $pathNameFile Name file and with path for replace .
*/
private function getValueTempFile ( $nameFile , $content )
{
global $config ;
$content = io_safe_output ( $content );
$content = $this -> replaceValues ( $content )[ 'command' ];
$nameTempDir = $config [ 'attachment_store' ] . '/temp_files/' ;
if ( file_exists ( $nameTempDir ) === false ) {
mkdir ( $nameTempDir );
}
$tmpPath = Files :: tempdirnam (
$nameTempDir ,
'temp_files_'
);
$pathNameFile = $tmpPath . '/' . $nameFile ;
file_put_contents ( $pathNameFile , $content );
return $pathNameFile ;
}
/**
* Return the correct value for pandora select
*
* @ param string $type Type of input .
* @ param string $id Value of the row macro .
*
* @ return string $id New id with the values replaced
*/
private function getValuePandoraSelect ( $type , $id )
{
$id = io_safe_output ( $id );
$idsArray = json_decode ( $id );
if ( is_array ( $idsArray ) === false ) {
$idsArray = [ $id ];
}
foreach ( $idsArray as $key => $v ) {
$value = false ;
switch ( $type ) {
case 'agent_groups' :
$value = groups_get_name ( $v );
break ;
case 'module_groups' :
$value = modules_get_modulegroup_name ( $v );
break ;
case 'tags' :
$value = tags_get_name ( $v );
break ;
case 'alert_templates' :
$value = alerts_get_alert_template_name ( $v );
break ;
case 'alert_actions' :
$value = alerts_get_alert_action_name ( $v );
break ;
case 'credentials.custom' :
$credentials = CredentialStore :: getKey ( $v );
$value = base64_encode (
json_encode (
[
'user' => $credentials [ 'username' ],
'password' => $credentials [ 'password' ],
]
)
);
break ;
case 'credentials.aws' :
$credentials = CredentialStore :: getKey ( $v );
$value = base64_encode (
json_encode (
[
'access_key_id' => $credentials [ 'username' ],
'secret_access_key' => $credentials [ 'password' ],
]
)
);
break ;
case 'credentials.azure' :
$credentials = CredentialStore :: getKey ( $v );
$value = base64_encode (
json_encode (
[
'client_id' => $credentials [ 'username' ],
'application_secret' => $credentials [ 'password' ],
'tenant_domain' => $credentials [ 'extra_1' ],
'subscription_id' => $credentials [ 'extra_2' ],
]
)
);
break ;
case 'credentials.gcp' :
$credentials = CredentialStore :: getKey ( $v );
$value = base64_encode ( $credentials [ 'extra_1' ]);
break ;
case 'credentials.sap' :
$credentials = CredentialStore :: getKey ( $v );
$value = base64_encode (
json_encode (
[
'user' => $credentials [ 'username' ],
'password' => $credentials [ 'password' ],
]
)
);
break ;
case 'credentials.snmp' :
$credentials = CredentialStore :: getKey ( $v );
$value = base64_encode ( $credentials [ 'extra_1' ]);
break ;
case 'credentials.wmi' :
$credentials = CredentialStore :: getKey ( $v );
$value = base64_encode (
json_encode (
[
'user' => $credentials [ 'username' ],
'password' => $credentials [ 'password' ],
'namespace' => $credentials [ 'extra_1' ],
]
)
);
break ;
case 'os' :
$value = get_os_name ( $v );
break ;
default :
continue ;
}
if ( $value !== false ) {
$id = str_replace ( $v , io_safe_output ( $value ), $id );
}
}
return $id ;
}
/**
* Encrypt and decode password with the user script .
*
* @ param string $password Password to encrypt .
* @ param boolean $decode True for decode password .
*
* @ return string Password encrypted
*/
private function encryptPassword ( $password , $decode = false )
{
global $config ;
if ( $decode === false ) {
$command = $this -> iniFile [ 'discovery_extension_definition' ][ 'passencrypt_exec' ];
$nameFile = $this -> iniFile [ 'discovery_extension_definition' ][ 'passencrypt_script' ];
$file = $config [ 'homedir' ] . $this -> path . '/' . $this -> mode . '/' . $nameFile ;
$command = str_replace ( '_passencrypt_script_' , $file , $command );
} else {
$command = $this -> iniFile [ 'discovery_extension_definition' ][ 'passdecrypt_exec' ];
$nameFile = $this -> iniFile [ 'discovery_extension_definition' ][ 'passdecrypt_script' ];
$file = $config [ 'homedir' ] . $this -> path . '/' . $this -> mode . '/' . $nameFile ;
$command = str_replace ( '_passdecrypt_script_' , $file , $command );
}
$command = str_replace ( '_password_' , $password , $command );
if ( empty ( $command ) === false ) {
return $this -> executeCommand ( $command );
} else {
return false ;
}
}
/**
* Valid the . ini
*
* @ param array $iniForValidate IniFile to validate .
*
* @ return mixed Return false if is ok and string for error .
*/
public static function validateIni ( $iniForValidate )
{
$discoveryExtension = $iniForValidate [ 'discovery_extension_definition' ];
if ( ! $discoveryExtension ) {
return __ ( 'The file does not contain the block \'discovery_extension_definition\'' );
}
if ( ! array_key_exists ( 'short_name' , $discoveryExtension )) {
return __ ( 'The \'discovery_extension_definition\' block must contain a \'short_name\' parameter' );
}
$defaultValues = $discoveryExtension [ 'default_value' ];
foreach ( $defaultValues as $key => $value ) {
if ( ! preg_match ( '/^_[a-zA-Z0-9]+_$/' , $key )) {
return __ (
'The \'discovery_extension_definition\' block \'default_value\' parameter has a key with invalid format. Use only letters (A-Z and a-z) and numbers (0-9) between opening and ending underscores (_): \'%s\'' ,
$key
);
}
}
$shortName = $discoveryExtension [ 'short_name' ];
if ( ! preg_match ( '/^[A-Za-z0-9._-]+$/' , $shortName )) {
return __ ( 'The \'discovery_extension_definition\' block \'short_name\' parameter contains illegal characters. Use only letters (A-Z and a-z), numbers (0-9), points (.), hyphens (-) and underscores (_)' );
}
if ( ! array_key_exists ( 'section' , $discoveryExtension ) || ! array_key_exists ( 'name' , $discoveryExtension )) {
return __ ( 'The \'discovery_extension_definition\' block must contain a \'section\' and a \'name\' parameters' );
}
$section = $discoveryExtension [ 'section' ];
$name = $discoveryExtension [ 'name' ];
if ( ! in_array ( $section , [ 'app' , 'cloud' , 'custom' ])) {
return __ ( 'The \'discovery_extension_definition\' block \'section\' parameter must be \'app\', \'cloud\' or \'custom\'' );
}
if ( empty ( $name )) {
return __ ( 'The \'discovery_extension_definition\' block \'name\' parameter can not be empty' );
}
if ( ! array_key_exists ( 'exec' , $discoveryExtension )) {
return __ ( 'The \'discovery_extension_definition\' block must contain an \'exec\' parameter' );
}
$execs = $discoveryExtension [ 'exec' ];
foreach ( $execs as $exec ) {
if ( empty ( $exec )) {
return __ ( 'All the \'discovery_extension_definition\' block \'exec\' parameter definitions can not be empty' );
}
}
$checkEmptyFields = [
'passencrypt_script' ,
'passencrypt_exec' ,
'passdecrypt_script' ,
'passdecrypt_exec' ,
];
foreach ( $checkEmptyFields as $key ) {
if ( $discoveryExtension [ $key ] !== null && empty ( $discoveryExtension [ $key ]) === true ) {
return __ ( 'The \'discovery_extension_definition\' block \'%s\' parameter can not be empty' , $key );
}
}
foreach ( $discoveryExtension [ 'execution_file' ] as $key => $value ) {
if ( ! preg_match ( '/^_[a-zA-Z0-9]+_$/' , $key )) {
return __ ( 'The \'discovery_extension_definition\' block \'execution_file\' parameter has a key with invalid format. Use only letters (A-Z and a-z) and numbers (0-9) between opening and ending underscores (_): \'%s\'' , $key );
}
if ( empty ( $value ) === true ) {
return __ ( 'All the \'discovery_extension_definition\' block \'execution_file\' parameter definitions can not be empty: \'%s\'' , $key );
}
}
if ( $iniForValidate [ 'config_steps' ] !== null && empty ( $iniForValidate [ 'config_steps' ]) === true ) {
return __ ( 'The \'config_steps\' block must contain a \'name\' parameter that can not be empty.' );
}
foreach ( $iniForValidate [ 'config_steps' ] as $key => $value ) {
foreach ( $value as $innerKey => $inner_value ) {
if ( isset ( $inner_steps [ $innerKey ])) {
$inner_steps [ $innerKey ][ $key ] = $inner_value ;
} else {
$inner_steps [ $innerKey ] = [ $key => $inner_value ];
}
}
}
$customFields = [];
foreach ( $inner_steps as $key => $step ) {
if ( is_numeric ( $key ) === false || $key === 0 ) {
return __ ( 'All the \'config_steps\' block parameters must use numbers greater than 0 as keys: \'%s\'.' , $key );
}
if ( empty ( $step [ 'name' ]) === true ) {
return __ ( 'The \'config_steps\' block must contain a \'name\' parameter for all the configuration steps: \'%s\'' , $key );
}
if ( empty ( $step [ 'custom_fields' ]) === true
&& empty ( $step [ 'script_data_fields' ]) === true
) {
return __ ( 'The \'config_steps\' block must contain a \'custom_fields\' or \'script_data_fields\' parameter that can not be empty' );
} else if ( empty ( $step [ 'custom_fields' ]) === false ) {
if ( empty ( $iniForValidate [ $step [ 'custom_fields' ]]) === true ) {
return __ ( 'The \'config_steps\' block \'custom_fields\' parameter has a key value reference that does not exist: \'%s\'' , $step [ 'custom_fields' ]);
} else {
$customFields [] = $step [ 'custom_fields' ];
}
}
$customFields [] = $step [ 'name' ];
}
$requiredKeys = [
'macro' ,
'name' ,
'type' ,
];
$validTypes = [
'string' ,
'number' ,
'password' ,
'textarea' ,
'checkbox' ,
'select' ,
'multiselect' ,
'tree' ,
];
$validSelectData = [
'agent_groups' ,
'agents' ,
'module_groups' ,
'modules' ,
'module_types' ,
'status' ,
'alert_templates' ,
'alert_actions' ,
'interval' ,
'tags' ,
'credentials.custom' ,
'credentials.aws' ,
'credentials.azure' ,
'credentials.sap' ,
'credentials.snmp' ,
'credentials.gcp' ,
'credentials.wmi' ,
'os' ,
];
$selectDataNames = [];
$treeDataNames = [];
foreach ( $customFields as $key => $customField ) {
$innerFields = [];
foreach ( $iniForValidate [ $customField ] as $key => $value ) {
foreach ( $value as $innerKey => $innerValue ) {
if ( isset ( $innerFields [ $innerKey ])) {
$innerFields [ $innerKey ][ $key ] = $innerValue ;
} else {
$innerFields [ $innerKey ] = [ $key => $innerValue ];
}
}
}
foreach ( $innerFields as $key => $field ) {
if ( is_numeric ( $key ) === false || $key === 0 ) {
return __ ( 'All the \'%s\' block parameters must use numbers greater than 0 as keys: \'%s\'.' , $customField , $key );
}
foreach ( $requiredKeys as $k => $value ) {
if ( empty ( $field [ $value ]) === true ) {
return __ ( 'The \'%s\' block \'%s\' parameter definitions can not be empty: \'%s\'.' , $customField , $value , $key );
}
}
if ( ! preg_match ( '/^_[a-zA-Z0-9]+_$/' , $field [ 'macro' ])) {
return __ ( 'The \'%s\' block \'macro\' parameter has a definition with invalid format. Use only letters (A-Z and a-z) and numbers (0-9) between opening and ending underscores (_): \'%s\'' , $customField , $field [ 'macro' ]);
}
if ( in_array ( $field [ 'type' ], $validTypes ) === false ) {
return __ ( 'The \'%s\' block \'type\' parameter has a definition with invalid value. Must be \'string\', \'number\', \'password\', \'textarea\', \'checkbox\', \'select\', \'multiselect\' or \'tree\': \'%s\'' , $customField , $field [ 'type' ]);
}
if ( $field [ 'type' ] === 'select' || $field [ 'type' ] === 'multiselect' ) {
if ( empty ( $field [ 'select_data' ]) === true ) {
return __ ( 'All the \'%s\' block \'select_data\' parameter definitions can not be empty: \'%s\'.' , $customField , $key );
} else if ( $iniForValidate [ $field [ 'select_data' ]] === null && in_array ( $field [ 'select_data' ], $validSelectData ) === false ) {
return __ (
'The \'%s\' block \'select_data\' parameter has a definition with invalid select type. Must be \'agent_groups\', \'agents\', \'module_groups\', \'modules\', \'module_types\', \'tags\', \'status\', \'alert_templates\', \'alert_actions\', \'interval\', \'credentials.custom\', \'credentials.aws\', \'credentials.azure\', \'credentials.gcp\', \'credentials.sap\', \'credentials.snmp\', \'os\' or an existint reference: \'%s\'' ,
$customField ,
$field [ 'select_data' ]
);
} else if ( $iniForValidate [ $field [ 'select_data' ]] !== null ) {
$selectDataNames [] = $field [ 'select_data' ];
}
}
if ( $field [ 'type' ] === 'tree' ) {
if ( empty ( $field [ 'tree_data' ]) === true ) {
return __ ( 'All the \'%s\' block \'tree_data\' parameter definitions can not be empty: \'%s\'' , $field [ 'macro' ], $key );
} else if ( $iniForValidate [ $field [ 'tree_data' ]] === null ) {
return __ ( 'The \'%s\' block \'tree_data\' parameter has a key value reference that does not exist: \'%s\'' , $customField , $field [ 'tree_data' ]);
} else {
$treeDataNames [] = $field [ 'tree_data' ];
}
}
if ( empty ( $field [ 'mandatory_field' ]) === false ) {
$validValues = [
'true' ,
'false' ,
'1' ,
'0' ,
'yes' ,
'no' ,
];
if ( in_array ( $field [ 'mandatory_field' ], $validValues ) === false ) {
return __ (
'The \'%s\' block \'mandatory_field\' parameter has a definition with invalid value. Must be \'true\' or \'false\', \'1\' or \'0\', \'yes\' or \'no\': \'%s\'' ,
$customField ,
$field [ 'mandatory_field' ]
);
}
}
if ( $field [ 'tip' ] !== null && empty ( $field [ 'tip' ]) === true ) {
return __ ( 'All the \'%s\' block \'tip\' parameter definitions can not be empty: \'%s\'.' , $customField , $key );
}
if ( $field [ 'placeholder' ] !== null && empty ( $field [ 'placeholder' ]) === true ) {
return __ ( 'All the \'%s\' block \'placeholder\' parameter definitions can not be empty: \'%s\'.' , $customField , $key );
}
if ( empty ( $field [ 'show_on_true' ]) === false ) {
if ( ! preg_match ( '/^_[a-zA-Z0-9]+_$/' , $field [ 'show_on_true' ])) {
return __ (
'The \'%s\' block \'show_on_true\' parameter has a definition with invalid format. Use only letters (A-Z and a-z) and numbers (0-9) between opening and ending underscores (_): \'%s\'' ,
$customField ,
$field [ 'show_on_true' ]
);
}
}
if ( empty ( $field [ 'encrypt_on_true' ]) === false ) {
if ( ! preg_match ( '/^_[a-zA-Z0-9]+_$/' , $field [ 'encrypt_on_true' ])) {
return __ (
'The \'%s\' block \'encrypt_on_true\' parameter has a definition with invalid format. Use only letters (A-Z and a-z) and numbers (0-9) between opening and ending underscores (_): \'%s\'' ,
$customField ,
$field [ 'encrypt_on_true' ]
);
}
}
}
}
foreach ( $treeDataNames as $key => $name ) {
$error = self :: validateTreeRecursive ( $name , $iniForValidate );
if ( $error !== false ) {
return $error ;
}
}
foreach ( $selectDataNames as $key => $name ) {
if ( empty ( $iniForValidate [ $name ][ 'option' ]) === true ) {
return __ ( 'The \'%s\' block must contain an \'option\' parameter' , $name );
}
foreach ( $iniForValidate [ $name ][ 'option' ] as $key => $option ) {
if ( empty ( $option ) === true ) {
return __ ( 'All the \'%s\' block \'option\' parameter definitions can not be empty: \'%s\'.' , $name , $key );
}
}
}
if ( $iniForValidate [ 'tempfile_confs' ] !== null && empty ( $iniForValidate [ 'tempfile_confs' ][ 'file' ]) === true ) {
return __ ( 'The \'tempfile_confs\' block must contain a \'file\' parameter.' );
}
foreach ( $iniForValidate [ 'tempfile_confs' ][ 'file' ] as $key => $tempfile ) {
if ( ! preg_match ( '/^_[a-zA-Z0-9]+_$/' , $key )) {
return __ (
'The \'tempfile_confs\' block \'file\' parameter has a key with invalid format. Use only letters (A-Z and a-z) and numbers (0-9) between opening and ending underscores (_): \'%s\'' ,
$key
);
}
if ( empty ( $tempfile ) === true ) {
return __ ( 'All the \'tempfile_confs\' block \'file\' parameter definitions can not be empty: \'%s\'.' , $key );
}
}
return false ;
}
/**
* Validate a tree recursively
*
* @ param string $dataTree Name of parent data_tree .
* @ param array $iniFile Inifile for search children .
* @ param array $parents Array of parents for recursive action , DO NOT SET .
*
* @ return boolean True if tree is correct .
*/
public static function validateTreeRecursive ( $dataTree , $iniFile , $parents = [])
{
$innerData = [];
$parents [] = $dataTree ;
foreach ( $iniFile [ $dataTree ] as $key => $value ) {
foreach ( $value as $innerKey => $innerValue ) {
if ( isset ( $innerData [ $innerKey ])) {
$innerData [ $innerKey ][ $key ] = $innerValue ;
} else {
$innerData [ $innerKey ] = [ $key => $innerValue ];
}
}
}
if ( count ( $innerData ) === 0 ) {
return __ ( 'The \'%s\' block must contain a \'name\' parameter that can not be empty.' , $dataTree );
}
foreach ( $innerData as $key => $prop ) {
if ( is_numeric ( $key ) === false || $key === 0 ) {
return __ ( 'All the \'%s\' block parameters must use numbers greater than 0 as keys: \'%s\'.' , $dataTree , $key );
}
if ( empty ( $prop [ 'name' ]) === true ) {
return __ ( 'The \'%s\' block must contain a \'name\' parameter for all the tree elements: \'%s\'.' , $dataTree , $key );
}
if ( $prop [ 'selectable' ] !== null && $prop [ 'selectable' ] === '' ) {
return __ ( 'All the \'%s\' block \'selectable\' parameter definitions can not be empty: \'%s\'.' , $dataTree , $key );
} else {
$validValues = [
'true' ,
'false' ,
'1' ,
'0' ,
'yes' ,
'no' ,
];
if ( in_array ( $prop [ 'selectable' ], $validValues ) === false ) {
return __ (
'The \'%s\' block \'selectable\' parameter has a definition with invalid value. Must be \'true\' or \'false\', \'1\' or \'0\', \'yes\' or \'no\': \'%s\'' ,
$dataTree ,
$prop [ 'selectable' ]
);
}
}
if ( $prop [ 'macro' ] !== null && ! preg_match ( '/^_[a-zA-Z0-9]+_$/' , $prop [ 'macro' ])) {
return __ (
'The \'%s\' block \'macro\' parameter has a definition with invalid format. Use only letters (A-Z and a-z) and numbers (0-9) between opening and ending underscores (_): \'%s\'' ,
$dataTree ,
$prop [ 'macro' ]
);
}
if ( $prop [ 'children' ] !== null && empty ( $iniFile [ $prop [ 'children' ]]) === true ) {
return __ ( 'The \'%s\' block \'children\' parameter has a key value reference that does not exist: \'%s\'' , $dataTree , $prop [ 'children' ]);
} else if ( in_array ( $prop [ 'children' ], $parents ) === true ) {
return __ ( 'The \'%s\' block \'children\' parameter has a key value reference to a parent tree element: \'%s\'' , $dataTree , $prop [ 'children' ]);
} else if ( empty ( $iniFile [ $prop [ 'children' ]]) === false ) {
$result = self :: validateTreeRecursive ( $prop [ 'children' ], $iniFile , $parents );
if ( $result !== false ) {
return $result ;
}
}
}
return false ;
}
/**
* Excute command with the timeout of the task .
*
* @ param string $command Command to execute .
*
* @ return string Output of command
*/
private function executeCommand ( $command )
{
$task = $this -> getTask ();
$timeout = $task [ 'executions_timeout' ];
$descriptors = [
0 => [
'pipe' ,
'r' ,
],
1 => [
'pipe' ,
'w' ,
],
2 => [
'pipe' ,
'w' ,
],
];
$process = proc_open ( $command , $descriptors , $pipes );
if ( ! is_resource ( $process )) {
return false ;
}
stream_set_blocking ( $pipes [ 1 ], 0 );
stream_set_blocking ( $pipes [ 2 ], 0 );
if ( ! $timeout ) {
$timeout = 5 ;
}
$real_timeout = ( $timeout * 1000000 );
$buffer = '' ;
while ( $real_timeout > 0 ) {
$start = microtime ( true );
$read = [ $pipes [ 1 ]];
$other = [];
stream_select ( $read , $other , $other , 0 , $real_timeout );
$status = proc_get_status ( $process );
$buffer .= stream_get_contents ( $pipes [ 1 ]);
if ( $status [ 'running' ] === false ) {
break ;
}
$real_timeout -= (( microtime ( true ) - $start ) * 1000000 );
}
if ( $real_timeout <= 0 ) {
proc_terminate ( $process , 9 );
fclose ( $pipes [ 0 ]);
fclose ( $pipes [ 1 ]);
fclose ( $pipes [ 2 ]);
proc_close ( $process );
return false ;
}
$errors = stream_get_contents ( $pipes [ 2 ]);
if ( empty ( $errors ) === false && empty ( $buffer )) {
proc_terminate ( $process , 9 );
fclose ( $pipes [ 0 ]);
fclose ( $pipes [ 1 ]);
fclose ( $pipes [ 2 ]);
proc_close ( $process );
return false ;
}
proc_terminate ( $process , 9 );
fclose ( $pipes [ 0 ]);
fclose ( $pipes [ 1 ]);
fclose ( $pipes [ 2 ]);
proc_close ( $process );
return $buffer ;
}
}