[pkg-nagios-changes] [Git][nagios-team/nagvis][upstream] New upstream version 1.9.48
Bas Couwenberg (@sebastic)
gitlab at salsa.debian.org
Wed Dec 3 19:58:28 GMT 2025
Bas Couwenberg pushed to branch upstream at Debian Nagios Maintainer Group / nagvis
Commits:
8edd31ee by Bas Couwenberg at 2025-12-03T20:47:01+01:00
New upstream version 1.9.48
- - - - -
18 changed files:
- .github/workflows/ci.yml
- ChangeLog
- + composer.json
- + composer.lock
- phpstan.neon
- share/frontend/nagvis-js/js/NagVisStatefulObject.js
- share/frontend/nagvis-js/js/ViewMap.js
- share/server/core/classes/CoreLogonMultisite.php
- share/server/core/classes/objects/NagVisStatefulObject.php
- share/server/core/defines/global.php
- share/server/core/defines/matches.php
- share/server/core/sources/general.php
- + share/userfiles/images/iconsets/std_area_error_ack.png
- + share/userfiles/images/iconsets/std_big_error_ack.png
- + share/userfiles/images/iconsets/std_dot_error_ack.png
- + share/userfiles/images/iconsets/std_geo_error_ack.png
- + share/userfiles/images/iconsets/std_medium_error_ack.png
- + share/userfiles/images/iconsets/std_small_error_ack.png
Changes:
=====================================
.github/workflows/ci.yml
=====================================
@@ -7,7 +7,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout at v3
- - name: PHPStan Static Analysis
- uses: php-actions/phpstan at v3
+ - uses: php-actions/composer at v6
+ - uses: php-actions/phpstan at v3
+ name: PHPStan Static Analysis
with:
path: .
=====================================
ChangeLog
=====================================
@@ -1,3 +1,12 @@
+1.9.48
+ * FIX: Fix exclude_members related PHP 8.1 compatibility issue (#400 Thanks to ekapsner-ne)
+ * FIX: misaligned labels on state changes
+ * Hide lines of excluded members in automaps (#402 Thanks to ekapsner-ne)
+ * Add support for SVG based icon sets (#405 Thanks to dnelson-nagios)
+ * FIX: session validity: only check cookie for site NagVis is running on
+ * FIX: Fix User enumeration and Cleanup CMK session cookie validation (CVE-2025-39665) (#411 Thanks to Shortfinga)
+ (CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N)
+
1.9.47
* FIX: Don't show complete backtrace if crashing. Now the backtrace is being logged to the apache error log
* FIX: Fix potential XSS via WYSIWYG editor. Now the option to edit these such elements is moved to a specific
=====================================
composer.json
=====================================
@@ -0,0 +1,16 @@
+{
+ "name": "nagvis/nagvis",
+ "description": "NagVis is a visualization addon for the well known network management system Nagios.",
+ "type": "project",
+ "license": "GPL-2.0-only",
+ "authors": [
+ {
+ "name": "Lars Michelsen",
+ "email": "lm at larsmichelsen.com"
+ }
+ ],
+ "minimum-stability": "stable",
+ "require-dev": {
+ "phpstan/phpstan": "^2.1"
+ }
+}
=====================================
composer.lock
=====================================
@@ -0,0 +1,77 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "c66e82eb768e45d79b25166eba80d003",
+ "packages": [],
+ "packages-dev": [
+ {
+ "name": "phpstan/phpstan",
+ "version": "2.1.18",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpstan.git",
+ "reference": "ee1f390b7a70cdf74a2b737e554f68afea885db7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ee1f390b7a70cdf74a2b737e554f68afea885db7",
+ "reference": "ee1f390b7a70cdf74a2b737e554f68afea885db7",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4|^8.0"
+ },
+ "conflict": {
+ "phpstan/phpstan-shim": "*"
+ },
+ "bin": [
+ "phpstan",
+ "phpstan.phar"
+ ],
+ "type": "library",
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "PHPStan - PHP Static Analysis Tool",
+ "keywords": [
+ "dev",
+ "static analysis"
+ ],
+ "support": {
+ "docs": "https://phpstan.org/user-guide/getting-started",
+ "forum": "https://github.com/phpstan/phpstan/discussions",
+ "issues": "https://github.com/phpstan/phpstan/issues",
+ "security": "https://github.com/phpstan/phpstan/security/policy",
+ "source": "https://github.com/phpstan/phpstan-src"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/ondrejmirtes",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/phpstan",
+ "type": "github"
+ }
+ ],
+ "time": "2025-07-17T17:22:31+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": {},
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {},
+ "platform-dev": {},
+ "plugin-api-version": "2.6.0"
+}
=====================================
phpstan.neon
=====================================
@@ -3,6 +3,7 @@ parameters:
paths:
- .
excludePaths:
+ - vendor
- share/frontend/nagvis-js/ext
- share/server/core/ext
- etc/conf.d/demo.ini.php
=====================================
share/frontend/nagvis-js/js/NagVisStatefulObject.js
=====================================
@@ -445,16 +445,12 @@ var NagVisStatefulObject = NagVisObject.extend({
this.bIsFlashing = show;
if(show) {
- oObjIcon.style.border = "5px solid " + sColor;
+ oObjIcon.style.outline = "5px solid " + sColor;
oObjIcon.classList.add(sFlashingClass);
- oObjIconDiv.style.top = (this.parseCoord(this.conf.y, 'y') - 5) + 'px';
- oObjIconDiv.style.left = (this.parseCoord(this.conf.x, 'x') - 5) + 'px';
oObjIconDiv.classList.add(sFlashingDivClass);
} else {
- oObjIcon.style.border = "none";
+ oObjIcon.style.outline = "none";
oObjIcon.classList.remove(sFlashingClass);
- oObjIconDiv.style.top = this.parseCoord(this.conf.y, 'y') + 'px';
- oObjIconDiv.style.left = this.parseCoord(this.conf.x, 'x') + 'px';
oObjIconDiv.classList.remove(sFlashingDivClass);
}
=====================================
share/frontend/nagvis-js/js/ViewMap.js
=====================================
@@ -221,6 +221,15 @@ var ViewMap = View.extend({
renderObject: function(object_id) {
var obj = this.objects[object_id];
+ var parents = obj.getParentObjectIds();
+
+ if (parents && usesSource('automap')){
+ for (var parentObjId in parents) {
+ if (!this.objects[parentObjId]){
+ return;
+ }
+ }
+ }
// FIXME: Are all these steps needed here?
obj.update();
@@ -234,7 +243,6 @@ var ViewMap = View.extend({
}
// Store object dependencies
- var parents = obj.getParentObjectIds();
if (parents) {
for (var parentObjId in parents) {
if (isset(this.objects[parentObjId])) this.objects[parentObjId].addChild(obj);
=====================================
share/server/core/classes/CoreLogonMultisite.php
=====================================
@@ -24,116 +24,30 @@
*****************************************************************************/
class CoreLogonMultisite extends CoreLogonModule {
- private $htpasswdPath;
- private $serialsPath;
- private $secretPath;
- private $cookieVersion;
- private $authFile;
-
- public function __construct() {
- $this->htpasswdPath = cfg('global', 'logon_multisite_htpasswd');
- $this->serialsPath = cfg('global', 'logon_multisite_serials');
- $this->secretPath = cfg('global', 'logon_multisite_secret');
- $this->cookieVersion = intval(cfg('global', 'logon_multisite_cookie_version'));
-
- // When the auth.serial file exists, use this instead of the htpasswd
- // for validating the cookie. The structure of the file is equal, so
- // the same code can be used.
- if(file_exists($this->serialsPath)) {
- $this->authFile = 'serial';
-
- } elseif(file_exists($this->htpasswdPath)) {
- $this->authFile = 'htpasswd';
-
- } else {
- throw new NagVisException(l('LogonMultisite: The htpasswd file "[HTPASSWD]" or '
- .'the authentication serial file "[SERIAL]" do not exist.',
- array('HTPASSWD' => $this->htpasswdPath, 'SERIAL' => $this->serialsPath)));
- }
+ private function isCookiePlausible($username, $sessionId, $cookieHash) {
+ // Mostly meant to check that we don't process malicious cookies, e.g.
+ // data with special chars.
- if(!file_exists($this->secretPath)) {
- $this->redirectToLogin();
+ if (preg_match('/^[\w$][- at .+\w$]*$/i', $username) !== 1){
+ // See https://github.com/Checkmk/checkmk/blob/1cc2796314508092b18d52d34b932fe0435beba4/packages/cmk-ccc/cmk/ccc/user.py#L52
+ throw new AuthenticationException(l("Malformed username"));
}
- }
-
- private function loadAuthFile($path) {
- $creds = array();
- foreach(file($path) AS $line) {
- if(strpos($line, ':') !== false) {
- list($username, $secret) = explode(':', $line, 2);
- $creds[$username] = rtrim($secret);
- }
+ if (preg_match('/^[-0-9a-f]{36}$/i', $sessionId) !== 1){
+ throw new AuthenticationException(l("Malformed session id"));
+ }
+ if (preg_match('/^[-0-9a-f]{64}$/i', $cookieHash) !== 1){
+ throw new AuthenticationException(l("Malformed hash"));
}
- return $creds;
- }
-
- private function loadSecret() {
- return file_get_contents($this->secretPath);
- }
-
- private function generateHash($username, $session_id, $user_secret) {
- $secret = $this->loadSecret();
- return hash_hmac("sha256", $username . $session_id. $user_secret, $secret);
- }
-
- private function generatePre22Hash($username, $session_id, $user_secret) {
- $secret = $this->loadSecret();
- return hash("sha256", $username . $session_id. $user_secret . $secret);
- }
-
- private function generatePre20Hash($username, $issue_time, $user_secret) {
- $secret = $this->loadSecret();
- return md5($username . $issue_time . $user_secret . $secret);
}
private function checkAuthCookie($cookieName) {
if(!isset($_COOKIE[$cookieName]) || $_COOKIE[$cookieName] == '') {
throw new AuthenticationException(l("No auth cookie provided."));
}
-
- // Checkmk 1.6+ may add double quotes round the value in some cases
- // (e.g. when @ signs are found in the value)
- $cookieValue = trim($_COOKIE[$cookieName], '"');
-
- // 2nd field is "issue time" in pre 2.0 cookies. Now it's the session ID
+ $cookieValue = $_COOKIE[$cookieName];
list($username, $sessionId, $cookieHash) = explode(':', $cookieValue, 3);
- if($this->authFile == 'htpasswd')
- $users = $this->loadAuthFile($this->htpasswdPath);
- else
- $users = $this->loadAuthFile($this->serialsPath);
-
- if(!isset($users[$username])) {
- throw new AuthenticationException(l("User not found in auth file."));
- }
- $user_secret = $users[$username];
-
- if ($this->cookieVersion < 1) {
- // Older Checkmk versions do not set the cookieVersion, therefore we guess based on the length.
-
- // Checkmk 2.0 changed the following:
- // a) 2nd field from "issue time" to session ID
- // b) 3rd field from md5 hash to sha256 hash
- // NagVis is used with older and newer Checkmk versions. Be compatible
- // to both cookie formats.
- $is_pre_20_cookie = strlen($cookieHash) == 32;
-
- if ($is_pre_20_cookie)
- $hash = $this->generatePre20Hash($username, $sessionId, (string) $user_secret);
- else
- $hash = $this->generatePre22Hash($username, $sessionId, (string) $user_secret);
- }
- elseif ($this->cookieVersion == 1) {
- $hash = $this->generateHash($username, $sessionId, (string) $user_secret);
- }
- else {
- throw new NagVisException(l('The Multisite Cookie version is not supported'));
- }
-
- // Validate the hash
- if (!hash_equals($hash, $cookieHash)) {
- throw new Exception();
- }
+ $this->isCookiePlausible($username, $sessionId, $cookieHash);
// Check session periods validity
$site = getenv('OMD_SITE');
@@ -156,7 +70,7 @@ class CoreLogonMultisite extends CoreLogonModule {
$context = stream_context_create($contextOptions);
if(filter_var(ini_get('allow_url_fopen'), FILTER_VALIDATE_BOOLEAN)) {
- $result = file_get_contents($url, false, $context);
+ $result = @ file_get_contents($url, false, $context);
if ($result === false) {
throw new AuthenticationException(l("Cookie is invalid."));
}
@@ -185,7 +99,7 @@ class CoreLogonMultisite extends CoreLogonModule {
// Loop all cookies trying to fetch a valid authentication
// cookie for this installation
foreach(array_keys($_COOKIE) AS $cookieName) {
- if(substr($cookieName, 0, 5) != 'auth_') {
+ if($cookieName != 'auth_' . getenv('OMD_SITE')) {
continue;
}
try {
=====================================
share/server/core/classes/objects/NagVisStatefulObject.php
=====================================
@@ -360,9 +360,9 @@ class NagVisStatefulObject extends NagVisObject {
public function getExcludeFilterKey($isCount) {
// When this is a count use the exclude_member_states over the
// exclude_members
- if($isCount && $this->exclude_member_states !== '')
+ if($isCount && $this->exclude_member_states != '')
return 'exclude_member_states';
- elseif($this->exclude_members !== '')
+ elseif($this->exclude_members != '')
return 'exclude_members';
else
return '';
=====================================
share/server/core/defines/global.php
=====================================
@@ -23,7 +23,7 @@
*****************************************************************************/
// NagVis Version
-define('CONST_VERSION', '1.9.47');
+define('CONST_VERSION', '1.9.48');
// Set PHP error handling to standard level
// Different levels for php versions below 5.1 because PHP 5.1 reports
=====================================
share/server/core/defines/matches.php
=====================================
@@ -71,7 +71,7 @@ define('MATCH_PNG_GIF_JPG_FILE_OR_URL', '/^((.+)\.(png|gif|jpg)|\[[0-9a-z\s:+[\]
define('MATCH_ROTATION_STEP_TYPES_EMPTY', '/^(?:map|url)?$/');
define('MATCH_LANGUAGE_EMPTY', '/^[a-zA-Z0-9\-_]*$/');
define('MATCH_LANGUAGE_FILE', '/^([^.].*)/');
-define('MATCH_ICONSET', '/^(.+)_ok.(png|gif|jpg)$/u');
+define('MATCH_ICONSET', '/^(.+)_ok.(png|gif|jpg|svg)$/u');
define('MATCH_BACKEND_FILE', '/^GlobalBackend([^MI].+)\.php$/');
define('MATCH_BACKEND_ID', '/^[0-9a-z._-]*$/iu');
define('MATCH_DOC_DIR', '/^([a-z]{2}_[A-Z]{2})/');
=====================================
share/server/core/sources/general.php
=====================================
@@ -50,14 +50,51 @@ function iconset_size($iconset) {
$fileType = $CORE->getIconsetFiletype($iconset);
$iconPath = path('sys', 'global', 'icons').'/'.$iconset.'_ok.'.$fileType;
$iconPathLocal = path('sys', 'local', 'icons').'/'.$iconset.'_ok.'.$fileType;
- if(file_exists($iconPathLocal))
- return getimagesize($iconPathLocal);
- elseif(file_exists($iconPath))
- return getimagesize($iconPath);
+ if(file_exists($iconPathLocal)) {
+ if($fileType == "svg") {
+ return svg_size($iconPathLocal);
+ }
+ else {
+ return getimagesize($iconPathLocal);
+ }
+ }
+ elseif(file_exists($iconPath)){
+ if($fileType == "svg") {
+ return svg_size($iconPath);
+ }
+ else {
+ return getimagesize($iconPath);
+ }
+ }
else
return array(0, 0);
}
+function svg_size($filepath) {
+ if (!file_exists($filepath)) {
+ return array(0, 0);
+ }
+
+ $doc = new DOMDocument();
+ $doc->load($filepath);
+
+ $svg = $doc->getElementsByTagName('svg')->item(0);
+ $width = $svg->getAttribute('width');
+ $height = $svg->getAttribute('height');
+
+ // Fallback to viewBox
+ if (empty($width) || empty($height)) {
+ $viewBox = $svg->getAttribute('viewBox');
+ $parts = preg_split('/[\s,]+/', $viewBox);
+ if (count($parts) === 4) {
+ $width = $parts[2];
+ $height = $parts[3];
+ }
+ }
+
+ return array(floatval($width), floatval($height));
+}
+
function shape_size($icon) {
$iconPath = path('sys', 'global', 'shapes').'/'.$icon;
$iconPathLocal = path('sys', 'local', 'shapes').'/'.$icon;
=====================================
share/userfiles/images/iconsets/std_area_error_ack.png
=====================================
Binary files /dev/null and b/share/userfiles/images/iconsets/std_area_error_ack.png differ
=====================================
share/userfiles/images/iconsets/std_big_error_ack.png
=====================================
Binary files /dev/null and b/share/userfiles/images/iconsets/std_big_error_ack.png differ
=====================================
share/userfiles/images/iconsets/std_dot_error_ack.png
=====================================
Binary files /dev/null and b/share/userfiles/images/iconsets/std_dot_error_ack.png differ
=====================================
share/userfiles/images/iconsets/std_geo_error_ack.png
=====================================
Binary files /dev/null and b/share/userfiles/images/iconsets/std_geo_error_ack.png differ
=====================================
share/userfiles/images/iconsets/std_medium_error_ack.png
=====================================
Binary files /dev/null and b/share/userfiles/images/iconsets/std_medium_error_ack.png differ
=====================================
share/userfiles/images/iconsets/std_small_error_ack.png
=====================================
Binary files /dev/null and b/share/userfiles/images/iconsets/std_small_error_ack.png differ
View it on GitLab: https://salsa.debian.org/nagios-team/nagvis/-/commit/8edd31ee4526fd4eccd790a4015ce8a1f52791a8
--
View it on GitLab: https://salsa.debian.org/nagios-team/nagvis/-/commit/8edd31ee4526fd4eccd790a4015ce8a1f52791a8
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-nagios-changes/attachments/20251203/aa4c1bfd/attachment-0001.htm>
More information about the pkg-nagios-changes
mailing list