From 4b24041a5cc7d699bd42ccbb82ca40ae2d6df1d8 Mon Sep 17 00:00:00 2001 From: Laurent Sulej Date: Tue, 24 Mar 2026 10:00:15 +0100 Subject: [PATCH] Adding the possibility to choose the SNMPv3 security level and context. Plus adapting the SNMP form to warn more precisely which field is needed in SNMPv3. There's two fields added to glpi_plugin_printercounters_snmpauthentications table: - context varchar(255) default '' - security_level tinyint not null default 0 The method setSNMPAuth(...) in inc/commonsnmpobject.class.php has been modified to take this new fields into account. And the inc/snmpauthentication.class.php has been adapted to present new fields and set the handlers for the security level dropdown list. TODO: Translations in other languages --- hook.php | 8 + inc/commonsnmpobject.class.php | 33 +-- inc/snmpauthentication.class.php | 230 ++++++++++++++------ install/sql/update-2.0.2-snmp-context.sql | 2 + install/sql/update-2.0.2-snmp-sec-level.sql | 2 + setup.php | 2 +- 6 files changed, 194 insertions(+), 83 deletions(-) create mode 100644 install/sql/update-2.0.2-snmp-context.sql create mode 100644 install/sql/update-2.0.2-snmp-sec-level.sql diff --git a/hook.php b/hook.php index f9fbfc2..ee11926 100644 --- a/hook.php +++ b/hook.php @@ -92,6 +92,14 @@ function plugin_printercounters_install() { $DB->runFile(PLUGIN_PRINTERCOUNTERS_DIR. "/install/sql/update-2.0.2.sql"); } + if (!$DB->fieldExists("glpi_plugin_printercounters_snmpauthentications", 'security_level')) { + $DB->runFile(PLUGIN_PRINTERCOUNTERS_DIR. "/install/sql/update-2.0.2-snmp-sec-level.sql"); + } + + if (!$DB->fieldExists("glpi_plugin_printercounters_snmpauthentications", 'context')) { + $DB->runFile(PLUGIN_PRINTERCOUNTERS_DIR. "/install/sql/update-2.0.2-snmp-context.sql"); + } + CronTask::Register('PluginPrintercountersItem_Ticket', 'PrintercountersCreateTicket', DAY_TIMESTAMP); CronTask::Register('PluginPrintercountersErrorItem', 'PluginPrintercountersErrorItem', DAY_TIMESTAMP); diff --git a/inc/commonsnmpobject.class.php b/inc/commonsnmpobject.class.php index ba6c03a..0874af7 100644 --- a/inc/commonsnmpobject.class.php +++ b/inc/commonsnmpobject.class.php @@ -171,19 +171,26 @@ public function setSNMPAuth($snmp_auth) { $snmp_auth['community'], $this->maxTimeout, $this->maxRetries); - - if (!empty($snmp_auth['authentication_encrypt']) - && !empty($snmp_auth['authentication_password']) - && !empty($snmp_auth['data_encrypt']) - && !empty($snmp_auth['data_password'])) { - $this->session->setSecurity('authPriv', - $snmp_auth['authentication_encrypt'], - $snmp_auth['authentication_password'], - $snmp_auth['data_encrypt'], - $snmp_auth['data_password'], '', ''); - } else { - throw new PluginPrintercountersException(__('Bad SNMP V3 parameters', 'printercounters'), 0, null, $this->items_id, $this->itemtype); - } + $is_security_OK = + $snmp_auth['security_level'] == 'noAuthNoPriv' + || + ! ( empty($snmp_auth['authentication_encrypt']) || + empty($snmp_auth['authentication_password']) ) + || + ( $snpm_auth['security_level'] == 'authPriv' && + ! ( empty($snmp_auth['data_encrypt']) || + empty($snmp_auth['data_password']) ) ) + ; + + if ( $is_security_OK ) { + $this->session->setSecurity($snmp_auth['security_level'], + $snmp_auth['authentication_encrypt'], + $snmp_auth['authentication_password'], + $snmp_auth['data_encrypt'], + $snmp_auth['data_password'], $snmp_auth['context'], ''); + } else { + throw new PluginPrintercountersException(__('Bad SNMP V3 parameters', 'printercounters'), 0, null, $this->items_id, $this->itemtype); + } break; default : diff --git a/inc/snmpauthentication.class.php b/inc/snmpauthentication.class.php index f2cf08b..16599ed 100644 --- a/inc/snmpauthentication.class.php +++ b/inc/snmpauthentication.class.php @@ -46,6 +46,11 @@ class PluginPrintercountersSnmpauthentication extends CommonDropdown { const SNMPV2 = 1; const SNMPV3 = 3; + // Security levels + const noAuthNoPriv = 0; + const authNoPriv = 1; + const authPriv = 2; + // Auth encryption const SHA = 1; const MD5 = 2; @@ -159,6 +164,24 @@ public function rawSearchOptions() { 'massiveaction' => true ]; + $tab[] = [ + 'id' => '51', + 'table' => $this->getTable(), + 'field' => 'context', + 'name' => __('Context', 'printercounters'), + 'datatype' => 'specific', + 'massiveaction' => true + ]; + + $tab[] = [ + 'id' => '52', + 'table' => $this->getTable(), + 'field' => 'security_level', + 'name' => __('Security level', 'printercounters'), + 'datatype' => 'specific', + 'massiveaction' => true + ]; + return $tab; } @@ -170,43 +193,51 @@ public function rawSearchOptions() { function getAdditionalFields() { $tab = [ - ['name' => 'version', - 'label' => __('Version'), - 'type' => 'specific', - 'list' => true], - ['name' => 'community', - 'label' => __('Community', 'printercounters'), - 'type' => 'text', - 'list' => true], - ['name' => 'community_write', - 'label' => __('Community write', 'printercounters'), - 'type' => 'text', - 'list' => true], - ['name' => 'authentication_encrypt', - 'label' => __('Authentication encryption', 'printercounters'), - 'type' => 'specific', - 'list' => true], - ['name' => 'data_encrypt', - 'label' => __('Data encryption', 'printercounters'), - 'type' => 'specific', - 'list' => true], - ['name' => 'user', - 'label' => __('User'), - 'type' => 'text', - 'list' => true], - ['name' => 'authentication_password', - 'label' => __('Authentication password', 'printercounters'), - 'type' => 'specific', - 'list' => true], - ['name' => 'data_password', - 'label' => __('Data password', 'printercounters'), - 'type' => 'specific', - 'list' => true], - ['name' => 'is_default', - 'label' => __('Is default', 'printercounters'), - 'type' => 'bool', - 'list' => true], - ]; + ['name' => 'version', + 'label' => __('Version'), + 'type' => 'specific', + 'list' => true], + ['name' => 'community', + 'label' => __('Community', 'printercounters'), + 'type' => 'text', + 'list' => true], + ['name' => 'community_write', + 'label' => __('Community write', 'printercounters'), + 'type' => 'text', + 'list' => true], + ['name' => 'context', + 'label' => __('Context', 'printercounters'), + 'type' => 'text', + 'list' => true], + ['name' => 'security_level', + 'label' => __('Security level', 'printercounters'), + 'type' => 'specific', + 'list' => true], + ['name' => 'authentication_encrypt', + 'label' => __('Authentication encryption', 'printercounters'), + 'type' => 'specific', + 'list' => true], + ['name' => 'data_encrypt', + 'label' => __('Data encryption', 'printercounters'), + 'type' => 'specific', + 'list' => true], + ['name' => 'user', + 'label' => __('User'), + 'type' => 'text', + 'list' => true], + ['name' => 'authentication_password', + 'label' => __('Authentication password', 'printercounters'), + 'type' => 'specific', + 'list' => true], + ['name' => 'data_password', + 'label' => __('Data password', 'printercounters'), + 'type' => 'specific', + 'list' => true], + ['name' => 'is_default', + 'label' => __('Is default', 'printercounters'), + 'type' => 'bool', + 'list' => true], + ]; return $tab; } @@ -232,6 +263,9 @@ function displaySpecificTypeField($ID, $field = [], array $options = []) { case 'version': self::dropdownVersion(['value' => $value]); break; + case 'security_level': + self::dropdownSecurityLevel(['value' => $value]); + break; case 'authentication_encrypt': self::dropdownAuthenticationEncryption(['value' => $value]); break; @@ -239,7 +273,7 @@ function displaySpecificTypeField($ID, $field = [], array $options = []) { self::dropdownDataEncryption(['value' => $value]); break; case 'authentication_password':case 'data_password': - echo ""; + echo ""; break; } } @@ -259,6 +293,8 @@ static function getSpecificValueToDisplay($field, $values, array $options = []) switch ($field) { case 'version' : return self::getVersion($values[$field]); + case 'security_level' : + return self::getSecurityLevel($values[$field]); case 'authentication_encrypt' : return self::getAuthenticationEncryption($values[$field]); case 'data_encrypt' : @@ -287,6 +323,8 @@ static function getSpecificValueToSelect($field, $name = '', $values = '', array switch ($field) { case 'version': return self::dropdownVersion($options); + case 'security_level': + return self::dropdownSecurityLevel($options); case 'authentication_encrypt': return self::dropdownAuthenticationEncryption($options); case 'data_encrypt': @@ -356,9 +394,8 @@ static function getAllVersionArray() { // To be overridden by class $tab = [self::SNMPV1 => __('SNMP v1', 'printercounters'), - self::SNMPV2 => __('SNMP v2c', 'printercounters'), - self::SNMPV3 => __('SNMP v3', 'printercounters')]; - + self::SNMPV2 => __('SNMP v2c', 'printercounters'), + self::SNMPV3 => __('SNMP v3', 'printercounters')]; return $tab; } @@ -393,9 +430,45 @@ static function getAllAuthenticationEncryptionArray() { // To be overridden by class $tab = [0 => Dropdown::EMPTY_VALUE, - self::SHA => __('SHA', 'printercounters'), - self::MD5 => __('MD5', 'printercounters')]; + self::SHA => __('SHA', 'printercounters'), + self::MD5 => __('MD5', 'printercounters')]; + return $tab; + } + + /** + * Show the SNMP security level dropdown + * + * @return an array + */ + static function dropdownSecurityLevel(array $options = []) { + return Dropdown::showFromArray('security_level', self::getAllSecurityLevelArray(), $options); + } + /** + * Function get the SNMP security level + * + * @param type $value + * @return type + */ + static function getSecurityLevel($value) { + if (!empty($value)) { + $data = self::getAllSecurityLevelArray(); + return $data[$value]; + } + } + + /** + * Get the SNMP security level list + * + * @return an array + */ + static function getAllSecurityLevelArray() { + + // To be overridden by class + $tab = [0 => Dropdown::EMPTY_VALUE, + self::noAuthNoPriv => __('noAuthNoPriv', 'printercounters'), + self::authNoPriv => __('authNoPriv', 'printercounters'), + self::authPriv => __('authPriv', 'printercounters')]; return $tab; } @@ -431,11 +504,10 @@ static function getAllDataEncryptionArray() { // To be overridden by class $tab = [0 => Dropdown::EMPTY_VALUE, - self::DES => __('DES', 'printercounters'), - self::AES128 => __('AES128', 'printercounters'), - self::AES192 => __('AES192', 'printercounters'), - self::AES256 => __('AES256', 'printercounters')]; - + self::DES => __('DES', 'printercounters'), + self::AES128 => __('AES128', 'printercounters'), + self::AES192 => __('AES192', 'printercounters'), + self::AES256 => __('AES256', 'printercounters')]; return $tab; } @@ -460,6 +532,8 @@ function getItemAuthentication($items_id, $itemtype) { `".$this->getTable()."`.`version`, `".$this->getTable()."`.`community`, `".$this->getTable()."`.`community_write`, + `".$this->getTable()."`.`security_level`, + `".$this->getTable()."`.`context`, `".$this->getTable()."`.`authentication_encrypt`, `".$this->getTable()."`.`data_encrypt`, `".$this->getTable()."`.`user`, @@ -475,13 +549,15 @@ function getItemAuthentication($items_id, $itemtype) { if ($DB->numrows($result)) { while ($data = $DB->fetchAssoc($result)) { $output[$data['items_id']] = ['version' => $data['version'], - 'community' => !empty($data['community']) ? $data['community'] : '', - 'community_write' => !empty($data['community_write']) ? $data['community_write'] : '', - 'authentication_encrypt' => !empty($data['authentication_encrypt']) ? self::getAuthenticationEncryption($data['authentication_encrypt']) : '', - 'data_encrypt' => !empty($data['data_encrypt']) ? self::getDataEncryption($data['data_encrypt']) : '', - 'user' => $data['user'], - 'authentication_password' => $data['authentication_password'], - 'data_password' => $data['data_password']]; + 'community' => !empty($data['community']) ? $data['community'] : '', + 'community_write' => !empty($data['community_write']) ? $data['community_write'] : '', + 'context' => !empty($data['context']) ? $data['context'] : '' , + 'security_level' => !empty($data['security_level']) ? self::getSecurityLevel($data['security_level']) : '', + 'authentication_encrypt' => !empty($data['authentication_encrypt']) ? self::getAuthenticationEncryption($data['authentication_encrypt']) : '', + 'data_encrypt' => !empty($data['data_encrypt']) ? self::getDataEncryption($data['data_encrypt']) : '', + 'user' => $data['user'], + 'authentication_password' => $data['authentication_password'], + 'data_password' => $data['data_password']]; } } } @@ -575,8 +651,8 @@ function checkMandatoryFields($input) { $checkKo = false; $mandatory_fields = ['name' => __('Name'), - 'community' => __('Community', 'printercounters'), - 'community_write' => __('Community write', 'printercounters')]; + 'community' => __('Community', 'printercounters'), + 'community_write' => __('Community write', 'printercounters')]; foreach ($input as $key => $value) { if (array_key_exists($key, $mandatory_fields)) { @@ -588,18 +664,34 @@ function checkMandatoryFields($input) { } // SNMP V3 - if ($input['version'] == self::SNMPV3 && empty($input['authentication_encrypt']) - && empty($input['authentication_password']) - && empty($input['data_encrypt']) - && empty($input['data_password'])) { - - $msg[] = __('Authentication encryption', 'printercounters'); - $msg[] = __('Data encryption', 'printercounters'); - $msg[] = __('User'); - $msg[] = __('Authentication password', 'printercounters'); - $msg[] = __('Data password', 'printercounters'); - - $checkKo = true; + if ($input['version'] == self::SNMPV3 ) { + $checkKo = false; + if ( empty($input['user'] ) ) { + $msg[] = __('User', 'printercounters'); + $checkKo = true; + } + if ( $input['security_level'] != self::noAuthNoPriv ) { // both authNoPriv and authPriv request authentication parameters + if ( empty($input['authentication_encrypt']) || empty($input['authentication_password']) ) { + if ( empty($input['authentication_encrypt']) ) { + $msg[] = __('Authentication encryption', 'printercounters'); + } + if( empty($input['authentication_password']) ) { + $msg[] = __('Authentication password', 'printercounters'); + } + $checkKo = true; + } + } + if ( $input['security_level'] == self::authPriv ) { + if ( empty($input['data_encrypt']) || empty($input['data_password']) ) { + if ( empty($input['data_encrypt']) ) { + $msg[] = __('Data encryption', 'printercounters'); + } + if ( empty($input['data_password']) ) { + $msg[] = __('Data password', 'printercounters'); + } + $checkKo = true; + } + } } if ($checkKo) { diff --git a/install/sql/update-2.0.2-snmp-context.sql b/install/sql/update-2.0.2-snmp-context.sql new file mode 100644 index 0000000..f36c1c1 --- /dev/null +++ b/install/sql/update-2.0.2-snmp-context.sql @@ -0,0 +1,2 @@ +ALTER TABLE `glpi_plugin_printercounters_snmpauthentications` + ADD `context` varchar(255) DEFAULT ''; diff --git a/install/sql/update-2.0.2-snmp-sec-level.sql b/install/sql/update-2.0.2-snmp-sec-level.sql new file mode 100644 index 0000000..4338c7b --- /dev/null +++ b/install/sql/update-2.0.2-snmp-sec-level.sql @@ -0,0 +1,2 @@ +ALTER TABLE `glpi_plugin_printercounters_snmpauthentications` + ADD `security_level` tinyint NOT NULL DEFAULT '0'; diff --git a/setup.php b/setup.php index ba4406d..f32a15e 100644 --- a/setup.php +++ b/setup.php @@ -27,7 +27,7 @@ -------------------------------------------------------------------------- */ -define('PLUGIN_PRINTERCOUNTERS_VERSION', '2.0.2'); +define('PLUGIN_PRINTERCOUNTERS_VERSION', '2.0.3'); if (!defined("PLUGIN_PRINTERCOUNTERS_DIR")) { define("PLUGIN_PRINTERCOUNTERS_DIR", Plugin::getPhpDir("printercounters"));