diff --git a/pandora_console/extras/discovery/DiscoveryApps.csv b/pandora_console/extras/discovery/DiscoveryApps.csv new file mode 100644 index 0000000000..ed4c110652 --- /dev/null +++ b/pandora_console/extras/discovery/DiscoveryApps.csv @@ -0,0 +1,18 @@ +pandorafms.aws.ec2;Amazon EC2;cloud;1;pandorafms.aws.ec2.png;https://pandorafms.com/library/aws-ec2-discovery/ +pandorafms.aws.rds;Amazon RDS;cloud;1;pandorafms.aws.rds.png;https://pandorafms.com/library/aws-rds-discovery/ +pandorafms.aws.s3;Amazon S3;cloud;1;pandorafms.aws.s3.png;https://pandorafms.com/library/aws-s3-discovery/ +pandorafms.azure.mc;Azure Microsoft Compute;cloud;1;pandorafms.azure.mc.png;https://pandorafms.com/library/aws-azure-discovery/ +pandorafms.db2;DB2;app;1;pandorafms.db2.png;https://pandorafms.com/library/db2-discovery/ +pandorafms.gcp.ce;Google Cloud Compute Engine;cloud;1;pandorafms.gcp.ce.png;https://pandorafms.com/library/google-cloud-discovery/ +pandorafms.mssql;Microsoft SQL Server;app;1;pandorafms.mssql.png;https://pandorafms.com/library/mssql-discovery/ +pandorafms.mysql;MySQL;app;1;pandorafms.mysql.png;https://pandorafms.com/library/mysql-discovery/ +pandorafms.oracle;Oracle;app;1;pandorafms.oracle.png;https://pandorafms.com/library/oracle-discovery/ +pandorafms.proxmox;Proxmox;app;0;pandorafms.proxmox.png;https://pandorafms.com/library/proxmox-discovery/ +pandorafms.sap.deset;SAP R3 - Deset;app;1;pandorafms.sap.deset.png;https://pandorafms.com/library/sap-discovery/ +pandorafms.vmware;VMware;app;1;pandorafms.vmware.png;https://pandorafms.com/library/vmware-discovery/ +pandorafms.kubernetes;Kubernetes;app;1;pandorafms.kubernetes.png;https://pandorafms.com/library/kubernetes-discovery/ +pandorafms.mongodb;MongoDB;app;1;pandorafms.mongodb.png;https://pandorafms.com/library/mongodb-discovery/ +pandorafms.ovh;OVH;cloud;1;pandorafms.ovh.png;https://pandorafms.com/library/ovh-discovery/ +pandorafms.vulnscan;Vulnerability Scanner;app;1;pandorafms.vulnscan.png;https://pandorafms.com/library/pandora-vulnerability-discovery/ +pandorafms.postgresql;PostgreSQL;app;1;pandorafms.postgresql.png;https://pandorafms.com/library/postgresql-discovery/ +pandorafms.xenserver;Xenserver;app;1;pandorafms.xenserver.png;https://pandorafms.com/library/xenserver-discovery/ diff --git a/pandora_console/godmode/wizards/Applications.class.php b/pandora_console/godmode/wizards/Applications.class.php index 7458aea872..f92a8cf0d6 100644 --- a/pandora_console/godmode/wizards/Applications.class.php +++ b/pandora_console/godmode/wizards/Applications.class.php @@ -212,6 +212,27 @@ class Applications extends Wizard Wizard::printBigButtonsList($wiz_data); + $not_defined_extensions = $extensions->loadExtensions(true); + + $output = html_print_div( + [ + 'class' => 'agent_details_line', + 'content' => ui_toggle( + Wizard::printBigButtonsList($not_defined_extensions, true), + ''.__('Not installed').'', + 'not_defined_apps', + 'not_defined_apps', + false, + true, + '', + '', + 'box-flat white_table_graph w100p' + ), + ], + ); + + echo $output; + echo '
*'.__('All company names used here are for identification purposes only. Use of these names, logos, and brands does not imply endorsement.').'
'; } diff --git a/pandora_console/godmode/wizards/Cloud.class.php b/pandora_console/godmode/wizards/Cloud.class.php index 2492322f3b..c464c49faa 100644 --- a/pandora_console/godmode/wizards/Cloud.class.php +++ b/pandora_console/godmode/wizards/Cloud.class.php @@ -232,6 +232,27 @@ class Cloud extends Wizard Wizard::printBigButtonsList($wiz_data); + $not_defined_extensions = $extensions->loadExtensions(true); + + $output = html_print_div( + [ + 'class' => 'agent_details_line', + 'content' => ui_toggle( + Wizard::printBigButtonsList($not_defined_extensions, true), + ''.__('Not installed').'', + 'not_defined_apps', + 'not_defined_apps', + false, + true, + '', + '', + 'box-flat white_table_graph w100p' + ), + ], + ); + + echo $output; + echo '
*'.__('All company names used here are for identification purposes only. Use of these names, logos, and brands does not imply endorsement.').'
'; } diff --git a/pandora_console/godmode/wizards/Custom.class.php b/pandora_console/godmode/wizards/Custom.class.php index 41a177b3e3..516b8d1e80 100644 --- a/pandora_console/godmode/wizards/Custom.class.php +++ b/pandora_console/godmode/wizards/Custom.class.php @@ -135,6 +135,27 @@ class Custom extends Wizard Wizard::printBigButtonsList($wiz_data); + $not_defined_extensions = $extensions->loadExtensions(true); + + $output = html_print_div( + [ + 'class' => 'agent_details_line', + 'content' => ui_toggle( + Wizard::printBigButtonsList($not_defined_extensions, true), + ''.__('Not installed').'', + 'not_defined_apps', + 'not_defined_apps', + false, + true, + '', + '', + 'box-flat white_table_graph w100p' + ), + ], + ); + + echo $output; + echo '
*'.__('All company names used here are for identification purposes only. Use of these names, logos, and brands does not imply endorsement.').'
'; return $result; } diff --git a/pandora_console/godmode/wizards/ManageExtensions.class.php b/pandora_console/godmode/wizards/ManageExtensions.class.php index 91ba1926e5..34c9950bc6 100644 --- a/pandora_console/godmode/wizards/ManageExtensions.class.php +++ b/pandora_console/godmode/wizards/ManageExtensions.class.php @@ -697,6 +697,9 @@ class ManageExtensions extends HTML $order, ); + $appsMetadata = self::loadDiscoveryAppsMetadata(); + $flattenMetadata = array_merge(...array_values($appsMetadata)); + $count = db_get_num_rows($sqlCount); foreach ($data as $key => $row) { @@ -705,6 +708,15 @@ class ManageExtensions extends HTML $logo = $this->defaultLogo; } + $metadataImage = $flattenMetadata[$row['short_name']]['image']; + + if (isset($metadataImage) === true + && file_exists($config['homedir'].'/images/discovery/'.$metadataImage) === true + && file_exists($this->path.'/'.$row['short_name'].'/logo.png') === false + ) { + $logo = '/images/discovery/'.$metadataImage; + } + $logo = html_print_image($logo, true, ['style' => 'max-width: 30px; margin-right: 15px;']); $data[$key]['name'] = $logo.io_safe_output($row['name']); $data[$key]['short_name'] = $row['short_name']; @@ -1490,4 +1502,55 @@ class ManageExtensions extends HTML } + /** + * Read metadata CSV from system and store data structure in memory. + * + * @return array Data structure. + */ + private static function loadDiscoveryAppsMetadata() + { + global $config; + + // Open the CSV file for reading. + $fileHandle = fopen($config['homedir'].'/extras/discovery/DiscoveryApps.csv', 'r'); + + // Check if the file was opened successfully. + if ($fileHandle !== false) { + $csvData = []; + + // Loop through each line in the CSV file. + while (($data = fgetcsv($fileHandle)) !== false) { + $csvData[] = explode(';', $data[0]); + } + + // Close the file handle. + fclose($fileHandle); + } + + $groupedArray = []; + + foreach ($csvData as $item) { + $key = $item[2]; + if (isset($groupedArray[$key]) === false) { + $groupedArray[$key] = []; + } + + $itemShortName = $item[0]; + unset($item[0]); + unset($item[2]); + + $itemIns = [ + 'name' => $item[1], + 'enterprise' => $item[3], + 'image' => $item[4], + 'url' => $item[5], + ]; + + $groupedArray[$key][$itemShortName] = $itemIns; + } + + return $groupedArray; + } + + } diff --git a/pandora_console/godmode/wizards/Wizard.main.php b/pandora_console/godmode/wizards/Wizard.main.php index a286b97fca..3bf60f805b 100644 --- a/pandora_console/godmode/wizards/Wizard.main.php +++ b/pandora_console/godmode/wizards/Wizard.main.php @@ -492,14 +492,43 @@ class Wizard $data['url'] = '#'; } + $cnt_class = 'data_container'; + $ent_icon = ''; + $label_class = ''; + + if (isset($data['ghost_mode']) === true + && $data['ghost_mode'] === true + ) { + $cnt_class .= ' alpha50'; + } + + if (isset($data['mark_as_enterprise']) === true + && $data['mark_as_enterprise'] === true + ) { + $ent_icon .= html_print_div( + [ + 'class' => 'w20px inline margin-lr-10', + 'content' => html_print_image( + 'images/ent_icon.png', + true, + ['class' => 'max-width-100p height_auto_important'] + ), + ], + true + ); + + $label_class = 'inline'; + } + ?>
  • -
    +
    -
  • @@ -514,11 +543,18 @@ class Wizard * * @return void Print the full list. */ - public static function printBigButtonsList($list_data) + public static function printBigButtonsList($list_data, $return=false) { + if ($return === true) { + ob_start(); + } echo ''; + + if ($return === true) { + return ob_get_clean(); + } } diff --git a/pandora_console/images/discovery/pandorafms.aws.ec2.png b/pandora_console/images/discovery/pandorafms.aws.ec2.png new file mode 100644 index 0000000000..46ae12b266 Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.aws.ec2.png differ diff --git a/pandora_console/images/discovery/pandorafms.aws.rds.png b/pandora_console/images/discovery/pandorafms.aws.rds.png new file mode 100644 index 0000000000..b118945b83 Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.aws.rds.png differ diff --git a/pandora_console/images/discovery/pandorafms.aws.s3.png b/pandora_console/images/discovery/pandorafms.aws.s3.png new file mode 100644 index 0000000000..2a52510ca4 Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.aws.s3.png differ diff --git a/pandora_console/images/discovery/pandorafms.azure.mc.png b/pandora_console/images/discovery/pandorafms.azure.mc.png new file mode 100644 index 0000000000..562cd52c66 Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.azure.mc.png differ diff --git a/pandora_console/images/discovery/pandorafms.db2.png b/pandora_console/images/discovery/pandorafms.db2.png new file mode 100644 index 0000000000..c16329bdb5 Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.db2.png differ diff --git a/pandora_console/images/discovery/pandorafms.gcp.ce.png b/pandora_console/images/discovery/pandorafms.gcp.ce.png new file mode 100644 index 0000000000..a971abc491 Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.gcp.ce.png differ diff --git a/pandora_console/images/discovery/pandorafms.kubernetes.png b/pandora_console/images/discovery/pandorafms.kubernetes.png new file mode 100644 index 0000000000..c0ebe64a4a Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.kubernetes.png differ diff --git a/pandora_console/images/discovery/pandorafms.mongodb.png b/pandora_console/images/discovery/pandorafms.mongodb.png new file mode 100644 index 0000000000..1042463eda Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.mongodb.png differ diff --git a/pandora_console/images/discovery/pandorafms.mssql.png b/pandora_console/images/discovery/pandorafms.mssql.png new file mode 100644 index 0000000000..3556b48572 Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.mssql.png differ diff --git a/pandora_console/images/discovery/pandorafms.mysql.png b/pandora_console/images/discovery/pandorafms.mysql.png new file mode 100644 index 0000000000..b24a84ceea Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.mysql.png differ diff --git a/pandora_console/images/discovery/pandorafms.oracle.png b/pandora_console/images/discovery/pandorafms.oracle.png new file mode 100644 index 0000000000..f8b41a81b4 Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.oracle.png differ diff --git a/pandora_console/images/discovery/pandorafms.ovh.png b/pandora_console/images/discovery/pandorafms.ovh.png new file mode 100644 index 0000000000..69eddb9a31 Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.ovh.png differ diff --git a/pandora_console/images/discovery/pandorafms.postgresql.png b/pandora_console/images/discovery/pandorafms.postgresql.png new file mode 100644 index 0000000000..e07c3b8871 Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.postgresql.png differ diff --git a/pandora_console/images/discovery/pandorafms.proxmox.png b/pandora_console/images/discovery/pandorafms.proxmox.png new file mode 100644 index 0000000000..d44d290de7 Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.proxmox.png differ diff --git a/pandora_console/images/discovery/pandorafms.sap.deset.png b/pandora_console/images/discovery/pandorafms.sap.deset.png new file mode 100644 index 0000000000..0132d8b8d3 Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.sap.deset.png differ diff --git a/pandora_console/images/discovery/pandorafms.vmware.png b/pandora_console/images/discovery/pandorafms.vmware.png new file mode 100644 index 0000000000..c4887f12e3 Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.vmware.png differ diff --git a/pandora_console/images/discovery/pandorafms.vulnscan.png b/pandora_console/images/discovery/pandorafms.vulnscan.png new file mode 100644 index 0000000000..63a118cc45 Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.vulnscan.png differ diff --git a/pandora_console/images/discovery/pandorafms.xenserver.png b/pandora_console/images/discovery/pandorafms.xenserver.png new file mode 100644 index 0000000000..0f9fd893fa Binary files /dev/null and b/pandora_console/images/discovery/pandorafms.xenserver.png differ diff --git a/pandora_console/images/ent_icon.png b/pandora_console/images/ent_icon.png new file mode 100644 index 0000000000..62dc5d22d7 Binary files /dev/null and b/pandora_console/images/ent_icon.png differ diff --git a/pandora_console/include/class/ExtensionsDiscovery.class.php b/pandora_console/include/class/ExtensionsDiscovery.class.php index 7fa1bfdb96..ee13e9a3a5 100644 --- a/pandora_console/include/class/ExtensionsDiscovery.class.php +++ b/pandora_console/include/class/ExtensionsDiscovery.class.php @@ -195,28 +195,200 @@ class ExtensionsDiscovery extends Wizard /** * Return array extensions filtered by section * - * @return array Extensions for + * @param boolean $not_defined_only Get only those extensions that are defined in the metadata CSV and not in db. + * + * @return array Extensions */ - public function loadExtensions() + public function loadExtensions($not_defined_only=false) { 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; + + define('NOT_FOUND_MSG', 1); + define('ENTERPRISE_MSG', 2); + define('URL_MSG', 3); + + $appsMetadata = self::loadDiscoveryAppsMetadata(); + $sectionMetadata = $appsMetadata[$this->section]; + + $anchor = html_print_anchor( + [ + 'href' => 'index.php?sec=gagente&sec2=godmode/agentes/configurar_agente&tab=alert', + 'content' => __('here'), + ], + true + ); + + // Print JS required for message management. + echo ''; + + if ($not_defined_only === true) { + // Case: search for those extensions defined in metadata CSV which are not in database. + $short_names_list = array_column($rows, 'short_name'); + + // Traverse apps in CSV metadata file and set properly those that do not exist in database. + foreach ($sectionMetadata as $short_name => $val) { + if (in_array($short_name, $short_names_list) === false) { + $logo = $this->path.'/'.$short_name.'/'.$val['image']; + if (file_exists($config['homedir'].$logo) === false) { + $logo = $this->defaultLogo; + } + + $error_msgs = []; + + if (isset($val['image']) === true + && file_exists($config['homedir'].'/images/discovery/'.$val['image']) === true + && file_exists($config['homedir'].$this->path.'/'.$short_name.'/'.$val['image']) === false + ) { + $logo = '/images/discovery/'.$val['image']; + } + + $url = ui_get_full_url( + 'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz='.$this->section.'&mode='.$extension['short_name'] + ); + + if (enterprise_installed() === false && ((bool) $val['enterprise'] === true)) { + // Display enterprise message if console is open and extension is enterprise. + $error_msgs[] = ENTERPRISE_MSG; + } + + $url_href = false; + if (isset($val['url']) === true + && $val['url'] !== '' + ) { + $url_href = $val['url']; + // Display URL message if an URL is defined in the metadata. + $error_msgs[] = URL_MSG; + } + + if (empty($error_msgs) === false) { + $json_errors = json_encode($error_msgs); + // Display messages dialog if there are some. + $url = 'javascript: showExtensionMsg(\''.$json_errors.'\', \''.$url_href.'\', \''.io_safe_input($val['name']).'\');'; + } + + $extensions[] = [ + 'icon' => $logo, + 'label' => io_safe_input($val['name']), + 'url' => $url, + 'ghost_mode' => true, + 'mark_as_enterprise' => (bool) $val['enterprise'], + 'defined' => false, + ]; + } + } + } else { + foreach ($rows as $key => $extension) { + $error_msgs = []; + + $logo = $this->path.'/'.$extension['short_name'].'/'.$this->icon; + if (file_exists($config['homedir'].$logo) === false) { + $logo = $this->defaultLogo; + } + + $mark_as_enterprise = false; + $ghostMode = false; + $url = ui_get_full_url( 'index.php?sec=gservers&sec2=godmode/servers/discovery&wiz='.$this->section.'&mode='.$extension['short_name'] - ), - ]; + ); + $url_href = false; + + $iniFileExists = self::iniFileExists($extension['short_name']); + + // Access metadata for current extension. + if (isset($sectionMetadata[$extension['short_name']]) === true) { + $itemData = $sectionMetadata[$extension['short_name']]; + + if (isset($itemData) === true) { + if (isset($itemData['image']) === true + && file_exists($config['homedir'].'/images/discovery/'.$itemData['image']) === true + && file_exists($config['homedir'].$this->path.'/'.$extension['short_name'].'/'.$this->icon) === false + ) { + $logo = '/images/discovery/'.$itemData['image']; + } + + $mark_as_enterprise = (bool) $itemData['enterprise']; + + if ($iniFileExists === false + && isset($itemData['url']) === true + && $itemData['url'] !== '' + ) { + $url_href = $itemData['url']; + // Display URL message if an URL is defined in the metadata. + $error_msgs[] = URL_MSG; + } + + if (enterprise_installed() === false + && (bool) $itemData['enterprise'] === true + ) { + // Set ghost mode and display enterprise message if console is open and extension is enterprise. + $error_msgs[] = ENTERPRISE_MSG; + $ghostMode = true; + } + + $itemName = $itemData['name']; + } + } + + if ($iniFileExists === false) { + // Set ghost mode and display not found message if ini file does not exist for extension. + $error_msgs[] = NOT_FOUND_MSG; + $ghostMode = true; + } + + if (empty($error_msgs) === false) { + $json_errors = json_encode($error_msgs); + // Display messages dialog if there are some. + $url = 'javascript: showExtensionMsg(\''.$json_errors.'\', \''.$url_href.'\', \''.io_safe_input($itemName).'\');'; + } + + $extensions[] = [ + 'icon' => $logo, + 'label' => $extension['name'], + 'url' => $url, + 'ghost_mode' => $ghostMode, + 'mark_as_enterprise' => $mark_as_enterprise, + 'defined' => true, + ]; + } } return $extensions; @@ -2553,4 +2725,69 @@ class ExtensionsDiscovery extends Wizard } + /** + * Read metadata CSV from system and store data structure in memory. + * + * @return array Data structure. + */ + private static function loadDiscoveryAppsMetadata() + { + global $config; + + // Open the CSV file for reading. + $fileHandle = fopen($config['homedir'].'/extras/discovery/DiscoveryApps.csv', 'r'); + + // Check if the file was opened successfully. + if ($fileHandle !== false) { + $csvData = []; + + // Loop through each line in the CSV file. + while (($data = fgetcsv($fileHandle)) !== false) { + $csvData[] = explode(';', $data[0]); + } + + // Close the file handle. + fclose($fileHandle); + } + + $groupedArray = []; + + foreach ($csvData as $item) { + $key = $item[2]; + if (isset($groupedArray[$key]) === false) { + $groupedArray[$key] = []; + } + + $itemShortName = $item[0]; + unset($item[0]); + unset($item[2]); + + $itemIns = [ + 'name' => $item[1], + 'enterprise' => $item[3], + 'image' => $item[4], + 'url' => $item[5], + ]; + + $groupedArray[$key][$itemShortName] = $itemIns; + } + + return $groupedArray; + } + + + /** + * Check if ini file exists for extension. + * + * @param string $shortName Extension short name. + * + * @return boolean Whether or not ini file exists. + */ + public static function iniFileExists($shortName) + { + global $config; + + $path = $config['homedir'].'/attachment/discovery/'.$shortName.'/discovery_definition.ini'; + return file_exists($path); + } } diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 53d559b1d0..71118e529a 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -8159,6 +8159,10 @@ div.graph div.legend table { height: auto; } +.height_auto_important { + height: auto !important; +} + .mx_height50px { max-height: 50px; } @@ -12304,6 +12308,12 @@ div.parent_graph > p.legend_background > table > tbody > tr { color: #82b92e; text-decoration: none; } + +.link-important { + color: #82b92e !important; + text-decoration: none !important; +} + .signature a { color: #82b92e; text-decoration: none;