From f7dbd8f3b2998a4c36a210eeec6e36d25366f862 Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Fri, 2 Feb 2024 14:41:28 +0100 Subject: [PATCH 1/7] Net scan improvements --- pandora_console/extras/mr/68.sql | 22 ++ .../godmode/wizards/HostDevices.class.php | 251 +++++++++--------- .../lib/PandoraFMS/DiscoveryServer.pm | 180 +++++++++---- pandora_server/lib/PandoraFMS/Recon/Base.pm | 97 +++++-- pandora_server/lib/PandoraFMS/Tools.pm | 28 +- 5 files changed, 365 insertions(+), 213 deletions(-) diff --git a/pandora_console/extras/mr/68.sql b/pandora_console/extras/mr/68.sql index db168d5c22..c84a04f2b7 100644 --- a/pandora_console/extras/mr/68.sql +++ b/pandora_console/extras/mr/68.sql @@ -56,5 +56,27 @@ ADD COLUMN `id_agent_data` int not null default 0 AFTER `script_type`; ALTER TABLE `tusuario` CHANGE COLUMN `metaconsole_data_section` `metaconsole_data_section` TEXT NOT NULL DEFAULT '' ; ALTER TABLE `tmensajes` ADD COLUMN `icon_notification` VARCHAR(250) NULL DEFAULT NULL AFTER `url`; +-- Create SNMPv3 credentials for recon tasks and update them +SET @creds_name = 'Recon-SNMP-creds-'; +INSERT IGNORE INTO `tcredential_store` (`identifier`, `id_group`, `product`, `extra_1`) + SELECT + CONCAT(@creds_name,`id_rt`) AS `identifier`, + `id_group`, + 'SNMP' AS `product`, + CONCAT( + '{', + '"community":"',`snmp_community`,'",', + '"version":"',`snmp_version`,'",', + '"securityLevelV3":"',`snmp_security_level`,'",', + '"authUserV3":"',`snmp_auth_user`,'",', + '"authMethodV3":"',`snmp_auth_method`,'",', + '"authPassV3":"',`snmp_auth_pass`,'",', + '"privacyMethodV3":"',`snmp_privacy_method`,'",', + '"privacyPassV3":"',`snmp_privacy_pass`,'"', + '}' + ) AS `extra1` + FROM `trecon_task` WHERE `snmp_version` = 3 AND `snmp_enabled` = 1 +; +UPDATE `trecon_task` SET `auth_strings` = IF(`auth_strings` = '',`auth_strings`,CONCAT(@creds_name,`id_rt`,',',`auth_strings`)) WHERE `snmp_version` = 3 AND `snmp_enabled` = 1; COMMIT; \ No newline at end of file diff --git a/pandora_console/godmode/wizards/HostDevices.class.php b/pandora_console/godmode/wizards/HostDevices.class.php index 4f0043f038..b3f59191f2 100755 --- a/pandora_console/godmode/wizards/HostDevices.class.php +++ b/pandora_console/godmode/wizards/HostDevices.class.php @@ -450,6 +450,26 @@ class HostDevices extends Wizard if (isset($this->task['id_rt']) === false) { // Create. + $default_templates = [ + io_safe_input('Linux System'), + io_safe_input('Windows System'), + io_safe_input('Windows Hardware'), + io_safe_input('Network Management') + ]; + + $default_templates_ids = db_get_all_rows_sql('SELECT id_np + FROM tnetwork_profile + WHERE name IN ('.implode(',', array_map(function($template) { + return "'" . $template . "'"; + }, $default_templates)).') + ORDER BY name'); + + if($default_templates_ids !== false) { + $this->task['id_network_profile'] = implode(',', + array_column($default_templates_ids, 'id_np'), + ); + } + $this->task['id_rt'] = db_process_sql_insert( 'trecon_task', $this->task @@ -1100,12 +1120,9 @@ class HostDevices extends Wizard 'arguments' => [ 'name' => 'id_network_profile[]', 'type' => 'select_from_sql', - 'sql' => 'SELECT tn.id_np, tn.name - FROM tnetwork_profile tn - LEFT JOIN `tnetwork_profile_pen` tp - ON tp.id_np = tn.id_np - WHERE tp.id_np IS NULL - ORDER BY tn.name', + 'sql' => 'SELECT id_np, name + FROM tnetwork_profile + ORDER BY name', 'return' => true, 'selected' => explode( ',', @@ -1273,114 +1290,88 @@ class HostDevices extends Wizard ], ]; - // SNMP Options pack v3. - $form['inputs'][] = [ - 'hidden' => 1, - 'block_id' => 'snmp_options_v3', - 'class' => 'indented', - 'block_content' => [ - [ - 'label' => ''.__('Context').'', - 'arguments' => [ - 'name' => 'snmp_context', - 'type' => 'text', - 'value' => $this->task['snmp_community'], - 'size' => 15, - 'return' => true, + $show_snmp_auth = false; + if (isset($this->task['snmp_enabled']) && $this->task['snmp_enabled'] > 0 + && isset($this->task['snmp_version']) && $this->task['snmp_version'] == 3 + ) { + $show_snmp_auth = true; + } - ], - ], - [ - 'label' => ''.__('Auth user').'', - 'arguments' => [ - 'name' => 'snmp_auth_user', - 'type' => 'text', - 'value' => $this->task['snmp_auth_user'], - 'size' => 15, - 'return' => true, - - ], - ], - [ - 'label' => ''.__('Security level').'', - 'arguments' => [ - 'name' => 'snmp_security_level', - 'type' => 'select', - 'fields' => [ - 'noAuthNoPriv' => __('Not auth and not privacy method'), - 'authNoPriv' => __('Auth and not privacy method'), - 'authPriv' => __('Auth and privacy method'), - ], - 'selected' => $this->task['snmp_security_level'], - 'size' => 15, - 'return' => true, - - ], - ], - [ - 'label' => ''.__('Auth method').'', - 'arguments' => [ - 'name' => 'snmp_auth_method', - 'type' => 'select', - 'fields' => [ - 'MD5' => __('MD5'), - 'SHA' => __('SHA'), - ], - 'selected' => $this->task['snmp_auth_method'], - 'size' => 15, - 'return' => true, - - ], - ], - [ - 'label' => ''.__('Auth password').''.ui_print_help_tip( - __( - 'The pass length must be eight character minimum.' - ), - true - ), - 'arguments' => [ - 'name' => 'snmp_auth_pass', - 'type' => 'password', - 'value' => $this->task['snmp_auth_pass'], - 'size' => 15, - 'return' => true, - - ], - ], - [ - 'label' => ''.__('Privacy method').'', - 'arguments' => [ - 'name' => 'snmp_privacy_method', - 'type' => 'select', - 'fields' => [ - 'DES' => __('DES'), - 'AES' => __('AES'), - ], - 'selected' => $this->task['snmp_privacy_method'], - 'size' => 15, - 'return' => true, - - ], - ], - [ - 'label' => ''.__('Privacy pass').''.ui_print_help_tip( - __( - 'The pass length must be eight character minimum.' - ), - true - ), - 'arguments' => [ - 'name' => 'snmp_privacy_pass', - 'type' => 'password', - 'value' => $this->task['snmp_privacy_pass'], - 'size' => 15, - 'return' => true, - - ], - ], + include_once $config['homedir'].'/include/class/CredentialStore.class.php'; + $all_snmp_keys = CredentialStore::getAll( + [ + 'cs.*', + 'tg.nombre as `group`', ], - ]; + ['product' => 'SNMP'] + ); + + if (is_array($all_snmp_keys) === true) { + // Improve usage and decode output. + $snmp_available_keys = array_reduce( + $all_snmp_keys, + function ($carry, $item) { + $item['extra_1'] = io_output_password($item['extra_1']); + + $extra1 = json_decode($item['extra_1'], true); + if($extra1 !== null && $extra1['version'] == 3) { + $carry[$item['identifier']] = $item['identifier']; + } + + return $carry; + }, + [] + ); + } + + hd($snmp_available_keys); + + if (check_acl($config['id_user'], 0, 'UM')) { + $link_to_cs = ''; + $link_to_cs .= __('No credentials available').', '; + $link_to_cs .= strtolower(__('Manage credentials')).''; + } else { + $link_to_cs = __('No credentials available'); + } + + if (count($snmp_available_keys) > 0) { + $form['inputs'][] = [ + 'block_id' => 'auth_block_snmp', + 'class' => 'indented', + 'hidden' => !$show_snmp_auth, + 'block_content' => [ + [ + 'label' => __('Credentials to try with'), + 'arguments' => [ + 'type' => 'select', + 'name' => 'auth_strings[]', + 'fields' => $snmp_available_keys, + 'selected' => explode( + ',', + $this->task['auth_strings'] + ), + + 'multiple' => true, + 'class' => 'select_multiple', + ], + ], + ], + ]; + } else { + $form['inputs'][] = [ + 'block_id' => 'auth_block_snmp', + 'class' => 'indented', + 'hidden' => !$show_snmp_auth, + 'block_content' => [ + [ + 'label' => __('Credentials'), + 'extra' => $link_to_cs, + ], + ], + ]; + } // Input: Enforce os detection. $form['inputs'][] = [ @@ -1453,14 +1444,12 @@ class HostDevices extends Wizard // AUTH CONFIGURATION. $show_auth = false; - if ((isset($this->task['wmi_enabled']) && $this->task['wmi_enabled'] > 0) - || (isset($this->task['rcmd_enabled']) && $this->task['rcmd_enabled'] > 0) - ) { + if (isset($this->task['wmi_enabled']) && $this->task['wmi_enabled'] > 0) { $show_auth = true; } include_once $config['homedir'].'/include/class/CredentialStore.class.php'; - $available_keys = CredentialStore::getKeys('WMI'); + $wmi_available_keys = CredentialStore::getKeys('WMI'); if (check_acl($config['id_user'], 0, 'UM')) { $link_to_cs = 'is_snmp_discovered($device)); my $community = $self->get_community($device); + my $snmp3_creds = undef; + if(defined($self->{'snmp3_auth_key'}{$device})) { + $snmp3_creds = $self->snmp3_credentials($self->{'snmp3_auth_key'}{$device}); + } + my $snmp3_params = { + 'custom_string_1' => '', + 'custom_string_2' => '', + 'custom_string_3' => '', + 'plugin_parameter' => '', + 'plugin_user' => '', + 'plugin_pass' => '' + }; + if(defined($snmp3_creds)) { + $community = $snmp3_creds->{'community'}; + $snmp3_params = { + 'custom_string_1' => $snmp3_creds->{'snmp_privacy_method'}, + 'custom_string_2' => $snmp3_creds->{'snmp_privacy_pass'}, + 'custom_string_3' => $snmp3_creds->{'snmp_security_level'}, + 'plugin_parameter' => $snmp3_creds->{'snmp_auth_method'}, + 'plugin_user' => $snmp3_creds->{'snmp_auth_user'}, + 'plugin_pass' => $snmp3_creds->{'snmp_auth_pass'} + }; + } + my @output = $self->snmp_get_value_array($device, $PandoraFMS::Recon::Base::IFINDEX); foreach my $if_index (@output) { next unless ($if_index =~ /^[0-9]+$/); @@ -1153,12 +1177,12 @@ sub PandoraFMS::Recon::Base::create_interface_modules($$) { ), 'ip_target' => $device, 'tcp_send' => $self->{'task_data'}{'snmp_version'}, - 'custom_string_1' => $self->{'task_data'}{'snmp_privacy_method'}, - 'custom_string_2' => $self->{'task_data'}{'snmp_privacy_pass'}, - 'custom_string_3' => $self->{'task_data'}{'snmp_security_level'}, - 'plugin_parameter' => $self->{'task_data'}{'snmp_auth_method'}, - 'plugin_user' => $self->{'task_data'}{'snmp_auth_user'}, - 'plugin_pass' => $self->{'task_data'}{'snmp_auth_pass'}, + 'custom_string_1' => $snmp3_params->{'snmp_privacy_method'}, + 'custom_string_2' => $snmp3_params->{'snmp_privacy_pass'}, + 'custom_string_3' => $snmp3_params->{'snmp_security_level'}, + 'plugin_parameter' => $snmp3_params->{'snmp_auth_method'}, + 'plugin_user' => $snmp3_params->{'snmp_auth_user'}, + 'plugin_pass' => $snmp3_params->{'snmp_auth_pass'}, 'snmp_community' => $community, 'snmp_oid' => "$PandoraFMS::Recon::Base::IFOPERSTATUS.$if_index", 'unit' => '' @@ -1183,12 +1207,12 @@ sub PandoraFMS::Recon::Base::create_interface_modules($$) { ), 'ip_target' => $device, 'tcp_send' => $self->{'task_data'}{'snmp_version'}, - 'custom_string_1' => $self->{'task_data'}{'snmp_privacy_method'}, - 'custom_string_2' => $self->{'task_data'}{'snmp_privacy_pass'}, - 'custom_string_3' => $self->{'task_data'}{'snmp_security_level'}, - 'plugin_parameter' => $self->{'task_data'}{'snmp_auth_method'}, - 'plugin_user' => $self->{'task_data'}{'snmp_auth_user'}, - 'plugin_pass' => $self->{'task_data'}{'snmp_auth_pass'}, + 'custom_string_1' => $snmp3_params->{'snmp_privacy_method'}, + 'custom_string_2' => $snmp3_params->{'snmp_privacy_pass'}, + 'custom_string_3' => $snmp3_params->{'snmp_security_level'}, + 'plugin_parameter' => $snmp3_params->{'snmp_auth_method'}, + 'plugin_user' => $snmp3_params->{'snmp_auth_user'}, + 'plugin_pass' => $snmp3_params->{'snmp_auth_pass'}, 'snmp_community' => $community, 'snmp_oid' => "$PandoraFMS::Recon::Base::IFHCINOCTECTS.$if_index", 'unit' => safe_input('bytes/s') @@ -1210,12 +1234,12 @@ sub PandoraFMS::Recon::Base::create_interface_modules($$) { ), 'ip_target' => $device, 'tcp_send' => $self->{'task_data'}{'snmp_version'}, - 'custom_string_1' => $self->{'task_data'}{'snmp_privacy_method'}, - 'custom_string_2' => $self->{'task_data'}{'snmp_privacy_pass'}, - 'custom_string_3' => $self->{'task_data'}{'snmp_security_level'}, - 'plugin_parameter' => $self->{'task_data'}{'snmp_auth_method'}, - 'plugin_user' => $self->{'task_data'}{'snmp_auth_user'}, - 'plugin_pass' => $self->{'task_data'}{'snmp_auth_pass'}, + 'custom_string_1' => $snmp3_params->{'snmp_privacy_method'}, + 'custom_string_2' => $snmp3_params->{'snmp_privacy_pass'}, + 'custom_string_3' => $snmp3_params->{'snmp_security_level'}, + 'plugin_parameter' => $snmp3_params->{'snmp_auth_method'}, + 'plugin_user' => $snmp3_params->{'snmp_auth_user'}, + 'plugin_pass' => $snmp3_params->{'snmp_auth_pass'}, 'snmp_community' => $community, 'snmp_oid' => "$PandoraFMS::Recon::Base::IFINOCTECTS.$if_index", 'unit' => safe_input('bytes/s') @@ -1241,12 +1265,12 @@ sub PandoraFMS::Recon::Base::create_interface_modules($$) { ), 'ip_target' => $device, 'tcp_send' => $self->{'task_data'}{'snmp_version'}, - 'custom_string_1' => $self->{'task_data'}{'snmp_privacy_method'}, - 'custom_string_2' => $self->{'task_data'}{'snmp_privacy_pass'}, - 'custom_string_3' => $self->{'task_data'}{'snmp_security_level'}, - 'plugin_parameter' => $self->{'task_data'}{'snmp_auth_method'}, - 'plugin_user' => $self->{'task_data'}{'snmp_auth_user'}, - 'plugin_pass' => $self->{'task_data'}{'snmp_auth_pass'}, + 'custom_string_1' => $snmp3_params->{'snmp_privacy_method'}, + 'custom_string_2' => $snmp3_params->{'snmp_privacy_pass'}, + 'custom_string_3' => $snmp3_params->{'snmp_security_level'}, + 'plugin_parameter' => $snmp3_params->{'snmp_auth_method'}, + 'plugin_user' => $snmp3_params->{'snmp_auth_user'}, + 'plugin_pass' => $snmp3_params->{'snmp_auth_pass'}, 'snmp_community' => $community, 'snmp_oid' => "$PandoraFMS::Recon::Base::IFHCOUTOCTECTS.$if_index", 'unit' => safe_input('bytes/s') @@ -1268,12 +1292,12 @@ sub PandoraFMS::Recon::Base::create_interface_modules($$) { ), 'ip_target' => $device, 'tcp_send' => $self->{'task_data'}{'snmp_version'}, - 'custom_string_1' => $self->{'task_data'}{'snmp_privacy_method'}, - 'custom_string_2' => $self->{'task_data'}{'snmp_privacy_pass'}, - 'custom_string_3' => $self->{'task_data'}{'snmp_security_level'}, - 'plugin_parameter' => $self->{'task_data'}{'snmp_auth_method'}, - 'plugin_user' => $self->{'task_data'}{'snmp_auth_user'}, - 'plugin_pass' => $self->{'task_data'}{'snmp_auth_pass'}, + 'custom_string_1' => $snmp3_params->{'snmp_privacy_method'}, + 'custom_string_2' => $snmp3_params->{'snmp_privacy_pass'}, + 'custom_string_3' => $snmp3_params->{'snmp_security_level'}, + 'plugin_parameter' => $snmp3_params->{'snmp_auth_method'}, + 'plugin_user' => $snmp3_params->{'snmp_auth_user'}, + 'plugin_pass' => $snmp3_params->{'snmp_auth_pass'}, 'snmp_community' => $community, 'snmp_oid' => "$PandoraFMS::Recon::Base::IFOUTOCTECTS.$if_index", 'unit' => safe_input('bytes/s') @@ -1305,19 +1329,19 @@ sub PandoraFMS::Recon::Base::create_interface_modules($$) { # Interface index filter. $macros->{'5'}->{'value'} = $if_index; # SecurityName. - $macros->{'6'}->{'value'} = $self->{'task_data'}->{'snmp_auth_user'}; + $macros->{'6'}->{'value'} = $snmp3_params->{'snmp_auth_user'}; # SecurityContext. $macros->{'7'}->{'value'} = $community; # SecurityLevel. - $macros->{'8'}->{'value'} = $self->{'task_data'}->{'snmp_security_level'}; + $macros->{'8'}->{'value'} = $snmp3_params->{'snmp_security_level'}; # AuthProtocol. - $macros->{'9'}->{'value'} = $self->{'task_data'}->{'snmp_auth_method'}; + $macros->{'9'}->{'value'} = $snmp3_params->{'snmp_auth_method'}; # AuthKey. - $macros->{'10'}->{'value'} = $self->{'task_data'}->{'snmp_auth_pass'}; + $macros->{'10'}->{'value'} = $snmp3_params->{'snmp_auth_pass'}; # PrivProtocol. - $macros->{'11'}->{'value'} = $self->{'task_data'}->{'snmp_privacy_method'}; + $macros->{'11'}->{'value'} = $snmp3_params->{'snmp_privacy_method'}; # PrivKey. - $macros->{'12'}->{'value'} = $self->{'task_data'}->{'snmp_privacy_pass'}; + $macros->{'12'}->{'value'} = $snmp3_params->{'snmp_privacy_pass'}; # Hash identifier. $macros->{'13'}->{'value'} = PandoraFMS::Tools::generate_agent_name_hash($if_name, $device); # Get input usage. @@ -1429,6 +1453,7 @@ sub PandoraFMS::Recon::Base::create_wmi_modules { { 'ip_target' => $target, 'snmp_oid' => "SELECT LoadPercentage FROM Win32_Processor WHERE DeviceId=\'$cpu\'", + 'tcp_send' => $creds->{'extra_1'}, 'plugin_user' => $creds->{'username'}, 'plugin_pass' => $creds->{'password'}, 'tcp_port' => 1, @@ -1449,6 +1474,7 @@ sub PandoraFMS::Recon::Base::create_wmi_modules { { 'ip_target' => $target, 'snmp_oid' => "SELECT FreePhysicalMemory, TotalVisibleMemorySize FROM Win32_OperatingSystem", + 'tcp_send' => $creds->{'extra_1'}, 'plugin_user' => $creds->{'username'}, 'plugin_pass' => $creds->{'password'}, 'tcp_port' => 0, @@ -1469,6 +1495,7 @@ sub PandoraFMS::Recon::Base::create_wmi_modules { { 'ip_target' => $target, 'snmp_oid' => "SELECT FreeSpace FROM Win32_LogicalDisk WHERE DeviceID='$unit'", + 'tcp_send' => $creds->{'extra_1'}, 'plugin_user' => $creds->{'username'}, 'plugin_pass' => $creds->{'password'}, 'tcp_port' => 1, @@ -1510,14 +1537,7 @@ sub PandoraFMS::Recon::Base::create_network_profile_modules($$) { # 1. Retrieve template info. my $template = get_nc_profile_advanced($self->{'dbh'}, $t_id); - # 2. Verify Private Enterprise Number matches (PEN) - if (defined($template->{'pen'})) { - my @pens = split(',', $template->{'pen'}); - - next unless (is_in_array(\@pens, $self->get_pen($device))); - } - - # 3. Retrieve module list from target template. + # 2. Retrieve module list from target template. my @np_components = get_db_rows( $self->{'dbh'}, 'SELECT * FROM tnetwork_profile_component WHERE id_np = ?', @@ -1525,7 +1545,7 @@ sub PandoraFMS::Recon::Base::create_network_profile_modules($$) { ); foreach my $np_component (@np_components) { - # 4. Register each module (candidate). 'add_module' will test them. + # 3. Register each module (candidate). 'add_module' will test them. my $component = get_db_single_row( $self->{'dbh'}, 'SELECT * FROM tnetwork_component WHERE id_nc = ?', @@ -1543,18 +1563,45 @@ sub PandoraFMS::Recon::Base::create_network_profile_modules($$) { } $component->{'name'} = safe_output($component->{'name'}); - if ($component->{'type'} >= 15 && $component->{'type'} <= 18) { - $component->{'snmp_community'} = safe_output($self->get_community($device)); + # SNMP Modules + if ($self->is_snmp_discovered($device) && $component->{'type'} >= 15 && $component->{'type'} <= 18) { + my $snmp3_creds = undef; + my $community = safe_output($self->get_community($device)); + if(defined($self->{'snmp3_auth_key'}{$device})) { + $snmp3_creds = $self->snmp3_credentials($self->{'snmp3_auth_key'}{$device}); + } + my $snmp3_params = { + 'custom_string_1' => '', + 'custom_string_2' => '', + 'custom_string_3' => '', + 'plugin_parameter' => '', + 'plugin_user' => '', + 'plugin_pass' => '' + }; + if(defined($snmp3_creds)) { + $community = $snmp3_creds->{'community'}; + $snmp3_params = { + 'custom_string_1' => $snmp3_creds->{'snmp_privacy_method'}, + 'custom_string_2' => $snmp3_creds->{'snmp_privacy_pass'}, + 'custom_string_3' => $snmp3_creds->{'snmp_security_level'}, + 'plugin_parameter' => $snmp3_creds->{'snmp_auth_method'}, + 'plugin_user' => $snmp3_creds->{'snmp_auth_user'}, + 'plugin_pass' => $snmp3_creds->{'snmp_auth_pass'} + }; + } + + $component->{'snmp_community'} = $community; $component->{'tcp_send'} = $self->{'snmp_version'}; - $component->{'custom_string_1'} = $self->{'snmp_privacy_method'}; - $component->{'custom_string_2'} = $self->{'snmp_privacy_pass'}; - $component->{'custom_string_3'} = $self->{'snmp_security_level'}; - $component->{'plugin_parameter'} = $self->{'snmp_auth_method'}; - $component->{'plugin_user'} = $self->{'snmp_auth_user'}; - $component->{'plugin_pass'} = $self->{'snmp_auth_pass'}; + $component->{'custom_string_1'} = $snmp3_params->{'snmp_privacy_method'}; + $component->{'custom_string_2'} = $snmp3_params->{'snmp_privacy_pass'}; + $component->{'custom_string_3'} = $snmp3_params->{'snmp_security_level'}; + $component->{'plugin_parameter'} = $snmp3_params->{'snmp_auth_method'}; + $component->{'plugin_user'} = $snmp3_params->{'snmp_auth_user'}; + $component->{'plugin_pass'} = $snmp3_params->{'snmp_auth_pass'}; } - if ($component->{'type'} >= 34 && $component->{'type'} <= 37) { + # RCMD Modules + if ($self->rcmd_responds($device) && $component->{'type'} >= 34 && $component->{'type'} <= 37) { # Update module credentials. $component->{'custom_string_1'} = $self->rcmd_credentials_key($device); $component->{'custom_string_2'} = pandora_get_os_by_id( @@ -1563,9 +1610,18 @@ sub PandoraFMS::Recon::Base::create_network_profile_modules($$) { ); } + # WMI Modules + if ($self->wmi_responds($device) && $component->{'id_modulo'} == 6) { + my $key = $self->wmi_credentials_key($device); + my $creds = $self->call('get_credentials', $key); + $component->{'tcp_send'} = $creds->{'extra_1'}; + $component->{'plugin_user'} = $creds->{'username'}; + $component->{'plugin_pass'} = $creds->{'password'}; + } + $component->{'__module_component'} = 1; - # 3. Try to register module into monitoring list. + # 4. Try to register module into monitoring list. $self->call('add_module', $device, $component); } } @@ -1576,13 +1632,23 @@ sub PandoraFMS::Recon::Base::create_network_profile_modules($$) { # Retrieve a key from credential store. ################################################################################ sub PandoraFMS::Recon::Base::get_credentials { - my ($self, $key_index) = @_; + my ($self, $key_index, $product) = @_; - return credential_store_get_key( + my $cred = credential_store_get_key( $self->{'pa_config'}, $self->{'dbh'}, $key_index ); + + if(defined($product)) { + if($product eq $cred->{'product'}) { + return $cred; + } else { + return undef; + } + } + + return $cred; } ################################################################################ diff --git a/pandora_server/lib/PandoraFMS/Recon/Base.pm b/pandora_server/lib/PandoraFMS/Recon/Base.pm index f21f13de4f..a84149c4dc 100644 --- a/pandora_server/lib/PandoraFMS/Recon/Base.pm +++ b/pandora_server/lib/PandoraFMS/Recon/Base.pm @@ -1352,10 +1352,9 @@ sub snmp_responds_v122c($$) { sub snmp_responds_v3($$) { my ($self, $device) = @_; - my $command = $self->snmp_get_command($device, ".0"); - `$command`; + $self->snmp3_credentials_calculation($device); - if ($? == 0) { + if ($self->snmp3_credentials_calculation($device)) { $self->mark_discovered($device); return 1; } @@ -1363,6 +1362,81 @@ sub snmp_responds_v3($$) { return 0; } +################################################################################ +# Get SNMP3 credentials info in HASH +################################################################################ +sub snmp3_credentials { + my ($self, $key) = @_; + + my $cred = $self->call('get_credentials', $key, 'SNMP'); + return undef if !defined($cred); + return undef if ref($cred) ne 'HASH'; + + my $extra1 = {}; + eval { + local $SIG{__DIE__}; + $extra1 = p_decode_json($self->{'pa_config'}, $cred->{'extra_1'}); + }; + if ($@) { + $self->call('message', "[".$key."] Credentials ERROR JSON: $@", 10); + return undef; + } + + return undef if $extra1->{'version'} ne '3'; + + return { + 'snmp_security_level' => $extra1->{'securityLevelV3'}, + 'snmp_privacy_method' => $extra1->{'privacyMethodV3'}, + 'snmp_privacy_pass' => $extra1->{'privacyPassV3'}, + 'snmp_auth_method' => $extra1->{'authMethodV3'}, + 'snmp_auth_user' => $extra1->{'authUserV3'}, + 'snmp_auth_pass' => $extra1->{'authPassV3'}, + 'community' => $extra1->{'community'} + }; +} + +################################################################################ +# Calculate WMI credentials for target, 1 if calculated, undef if cannot +# connect to target. Credentials could be empty (-N) +################################################################################ +sub snmp3_credentials_calculation { + my ($self, $target) = @_; + + # Test all credentials selected. + foreach my $key_index (@{$self->{'auth_strings_array'}}) { + my $cred = snmp3_credentials($key_index); + next if !defined($cred); + next if ref($cred) ne 'HASH'; + + my $auth = ''; + if ($cred->{'community'}) { # Context + $auth .= " -N \'$cred->{'community'}\' "; + } + $auth .= " -l$cred->{'snmp_security_level'} "; + if ($cred->{'snmp_security_level'} ne "noAuthNoPriv") { + $auth .= " -u$cred->{'snmp_auth_user'} -a $cred->{'snmp_auth_method'} -A \'$cred->{'snmp_auth_pass'}\' "; + } + if ($cred->{'snmp_security_level'} eq "authPriv") { + $auth .= " -x$cred->{'snmp_privacy_method'} -X \'$cred->{'snmp_privacy_pass'}\' "; + } + + $self->{'snmp3_auth'}{$target} = $auth; + $self->{'snmp3_auth_key'}{$target} = $key_index; + + my $command = $self->snmp_get_command($target, ".0"); + `$command`; + + if ($? == 0) { + return 1; + } + } + + delete($self->{'snmp3_auth'}{$target}); + delete($self->{'snmp3_auth_key'}{$target}); + + return 0; +} + ################################################################################ # Parse the local ARP cache. ################################################################################ @@ -2198,16 +2272,7 @@ sub snmp_get_command { my $command = "snmpwalk -M$DEVNULL -r$self->{'snmp_checks'} -t$self->{'snmp_timeout'} -v$self->{'snmp_version'} -On -Oe "; if ($self->{'snmp_version'} eq "3") { - if ($self->{'community'}) { # Context - $command .= " -N \'$self->{'community'}\' "; - } - $command .= " -l$self->{'snmp_security_level'} "; - if ($self->{'snmp_security_level'} ne "noAuthNoPriv") { - $command .= " -u$self->{'snmp_auth_user'} -a $self->{'snmp_auth_method'} -A \'$self->{'snmp_auth_pass'}\' "; - } - if ($self->{'snmp_security_level'} eq "authPriv") { - $command .= " -x$self->{'snmp_privacy_method'} -X \'$self->{'snmp_privacy_pass'}\' "; - } + $command .= " $self->{'snmp3_auth'}{$device} "; } else { $command .= " -c\'$community\'$vlan "; } @@ -2353,7 +2418,8 @@ sub wmi_credentials_calculation { # Test all credentials selected. foreach my $key_index (@{$self->{'auth_strings_array'}}) { - my $cred = $self->call('get_credentials', $key_index); + my $cred = $self->call('get_credentials', $key_index, 'WMI'); + next if !defined($cred); next if ref($cred) ne 'HASH'; my $auth = $cred->{'username'}.'%'.$cred->{'password'}; @@ -2431,7 +2497,8 @@ sub rcmd_credentials_calculation { # Test all credentials selected. foreach my $key_index (@{$self->{'auth_strings_array'}}) { - my $cred = $self->call('get_credentials', $key_index); + my $cred = $self->call('get_credentials', $key_index, 'CUSTOM'); + next if !defined($cred); next if ref($cred) ne 'HASH'; $rcmd->clean_ssh_lib(); diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index 543ea45556..37d9ece692 100755 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -716,19 +716,23 @@ sub credential_store_get_key($$$) { my $sql = 'SELECT * FROM tcredential_store WHERE identifier = ?'; my $key = PandoraFMS::DB::get_db_single_row($dbh, $sql, $identifier); - return { - 'username' => PandoraFMS::Core::pandora_output_password( - $pa_config, - $key->{'username'} - ), - 'password' => PandoraFMS::Core::pandora_output_password( - $pa_config, - $key->{'password'} - ), - 'extra_1' => $key->{'extra_1'}, - 'extra_2' => $key->{'extra_2'}, - }; + if(defined($key)) { + return { + 'product' => $key->{'product'}, + 'username' => PandoraFMS::Core::pandora_output_password( + $pa_config, + $key->{'username'} + ), + 'password' => PandoraFMS::Core::pandora_output_password( + $pa_config, + $key->{'password'} + ), + 'extra_1' => $key->{'extra_1'}, + 'extra_2' => $key->{'extra_2'}, + }; + } + return undef; } ################################################################################ From d1c6c9843bb1f5079851e664fa103f3d4f10ac27 Mon Sep 17 00:00:00 2001 From: Enrique Martin Date: Mon, 5 Feb 2024 23:26:55 +0100 Subject: [PATCH 2/7] Added net scan options to welcome wizard --- .../godmode/wizards/HostDevices.class.php | 6 +- .../include/ajax/task_to_perform.php | 7 +- .../include/class/WelcomeWindow.class.php | 344 +++++++++++++++++- .../include/functions_welcome_wizard.php | 90 ++++- 4 files changed, 433 insertions(+), 14 deletions(-) diff --git a/pandora_console/godmode/wizards/HostDevices.class.php b/pandora_console/godmode/wizards/HostDevices.class.php index b3f59191f2..c6b5c20c1a 100755 --- a/pandora_console/godmode/wizards/HostDevices.class.php +++ b/pandora_console/godmode/wizards/HostDevices.class.php @@ -1324,8 +1324,6 @@ class HostDevices extends Wizard ); } - hd($snmp_available_keys); - if (check_acl($config['id_user'], 0, 'UM')) { $link_to_cs = ' '', + 'content' => '
To detect and find systems on your network we will need access credentials. The SNMP community for network devices, and at least one set of credentials for Linux and Windows environments (they do not need to be super administrators, but they do need to be able to connect remotely). Without the credentials, we will only be able to detect if the devices are connected to the network.

', + ], + true + ); + + // SNMP Communities + echo html_print_label_input_block( + __('SNMP communities to try with').ui_print_help_tip( + __( + 'You can specify several values, separated by commas, for example: public,mysecret,1234' + ), + true + ), + html_print_input( + [ + 'name' => 'community', + 'type' => 'text', + 'value' => 'public', + 'size' => 25, + 'return' => true + ], + 'div', + true + ), + [ + 'div_id' => 'snmp-communities-div' + ] + ); + ui_require_jquery_file('tag-editor.min','include/javascript/',true); + ui_require_jquery_file('caret.min','include/javascript/',true); + ui_require_css_file('jquery.tag-editor','include/styles/',true); + + echo '
'; + + // WMI Credentials + echo html_print_label_input_block( + __('WMI credentials'), + html_print_div( + [ + 'id' => 'wmi-creds', + 'content' => '' + ], + true + ) + ); + echo html_print_div( + [ + 'id' => 'wmi-cred-form', + 'hidden' => true, + 'style' => 'margin: 3px; display: flex; align-items: center;', + 'content' => html_print_div( + [ + 'id' => 'wmi-cred-user-div', + 'style' => 'width: 260px;', + 'content' => html_print_label_input_block(' '.__('User').' ', html_print_input_text( + 'wmi-cred-user', + '', + '', + false, + 50, // Max length + true, + false, + true, + '', + 'w100p', + '', + 'off', + false, + '', + '', + '', + false, + '', + 'Username' + ),['div_style' => 'display: flex; align-items: center;']) + ], + true + ) + . + html_print_div( + [ + 'id' => 'wmi-cred-pass-div', + 'style' => 'width: 260px;', + 'content' => html_print_label_input_block(' '.__('Password').' ', html_print_input_password( + 'wmi-cred-pass', + '', + '', + false, + 50, // Max length + true, + false, + true, + 'w100p', + 'off', + false, + '' + ),['div_style' => 'display: flex; align-items: center;']) + ], + true + ) + . + html_print_div( + [ + 'id' => 'wmi-cred-namespace-div', + 'style' => 'width: 260px;', + 'content' => html_print_label_input_block(' '.__('Namespace').' ', html_print_input_text( + 'wmi-cred-namespace', + '', + '', + false, + 50, // Max length + true, + false, + true, + '', + 'w100p', + '', + 'off', + false, + '', + '', + '', + false, + '', + 'Namespace' + ),['div_style' => 'display: flex; align-items: center;']) + ], + true + ) + . + '
'.html_print_image( + 'images/delete.svg', + true, + [ + 'title' => __('Delete'), + 'style' => 'cursor: pointer;', + 'class' => 'main_menu_icon invert_filter', + ] + ).'' + ], + true + ); + echo '
'; + echo html_print_button( + __('Add'), + 'add-wmi-cred', + false, + 'add_discovery_credential("wmi-cred-form","wmi-creds");', + [ + 'icon' => 'plus', + 'mode' => 'secondary', + 'class' => 'mini' + ], + true, + false, + false, + '' + ); + + echo '
'; + + // RCM Credentials + echo html_print_label_input_block( + __('Remote commands credentials'), + html_print_div( + [ + 'id' => 'rcmd-creds', + 'content' => '' + ], + true + ) + ); + echo html_print_div( + [ + 'id' => 'rcmd-cred-form', + 'hidden' => true, + 'style' => 'margin: 3px; display: flex; align-items: center;', + 'content' => html_print_div( + [ + 'id' => 'rcmd-cred-user-div', + 'style' => 'width: 260px;', + 'content' => html_print_label_input_block(' '.__('User').' ', html_print_input_text( + 'rcmd-cred-user', + '', + '', + false, + 50, // Max length + true, + false, + true, + '', + 'w100p', + '', + 'off', + false, + '', + '', + '', + false, + '', + 'Username' + ),['div_style' => 'display: flex; align-items: center;']) + ], + true + ) + . + html_print_div( + [ + 'id' => 'rcmd-cred-pass-div', + 'style' => 'width: 260px;', + 'content' => html_print_label_input_block(' '.__('Password').' ', html_print_input_password( + 'rcmd-cred-pass', + '', + '', + false, + 50, // Max length + true, + false, + true, + 'w100p', + 'off', + false, + '' + ),['div_style' => 'display: flex; align-items: center;']) + ], + true + ) + . + ''.html_print_image( + 'images/delete.svg', + true, + [ + 'title' => __('Delete'), + 'style' => 'cursor: pointer;', + 'class' => 'main_menu_icon invert_filter', + ] + ).'' + ], + true + ); + echo '
'; + echo html_print_button( + __('Add'), + 'add-rcmd-cred', + false, + 'add_discovery_credential("rcmd-cred-form","rcmd-creds");', + [ + 'icon' => 'plus', + 'mode' => 'secondary', + 'class' => 'mini' + ], + true, + false, + false, + '' + ); + echo html_print_submit_button(__('Create'), 'basic_net', false, ['icon' => 'next', 'style' => 'margin-top:15px; float:right;']); ?> +