security: consolidate verified GHSA fixes for develop (batch 4) (#8145)

* security: consolidate verified GHSA fixes for develop (batch 4)

Develop counterparts of the 1.2.x batch-4 fixes in #8144, re-verified against
current develop HEAD.

- GHSA-4rmr-wvjq-qxc2: include/auth.php Basic Auth and guest branches fall
  through to the per-page realm check instead of returning early.
- GHSA-j67j-wpm4-9g3x: the pre-dispatch update_policy branch in user_admin.php
  and user_group_admin.php requires a CSRF-token POST. The denylist -> allowlist
  redesign is tracked for 1.3 in #8143.
- GHSA-2p3x-f5jm-rg6p: the View-Graphs -> poller RCE chain is broken by the
  realm check (4rmr), the update_policy guard (j67j) and shell-free webhits (x5pw).
- GHSA-x5pw-cg7j-mj4r: scripts/webhits.pl runs wc through a shell-free list-form open.
- GHSA-9737-rqh3-h7fh: names interpolated into raise_message() now use __esc()
  across the UI; URL- and HTML-bearing messages are excluded.
- GHSA-9x9h-2577-9w86: the colordropdown input is built as a node and the label
  is no longer round-tripped through parseHTML (the list item already used
  createTextNode on develop).
- GHSA-h96j-8xhc-2p3w: remote_agent.php authorizes on $_SERVER['REMOTE_ADDR'],
  not get_client_addr(), which honours client-settable proxy headers.

Regression guards under tests/Unit/Security/{Auth,Csrf,Xss,ShellInjection}.
php -l, check-changelog.py and the sink/architectural baselines all pass.

* chore: reference PR #8145 on the batch-4 1.3.0-dev CHANGELOG entries

* security: resolve develop merge - keep id-only xmlerror unescaped (matches #8141 h745 test)

* security(GHSA-j67j): use REQUEST_METHOD POST guard instead of raw \ (hardening-pattern-guard)

* security(GHSA-9737): fix review findings - drop double-encoding in __esc, escape missed name sinks, correct plugins format-arg count
This commit is contained in:
TheWitness authored and GitHub committed 2026-10-02 13:10:42 -04:00
1 parent 0055dd00cc
commit 41e6d9e033
38 files changed
+392 -156

No files matched your search

+21
View File
@@ -1,6 +1,27 @@
Cacti CHANGELOG
1.3.0-dev
-security#GHSA-4rmr-wvjq-qxc2: Run the per-page realm check after Basic Auth and guest login instead of returning early (#8145)
-security#GHSA-j67j-wpm4-9g3x: Require a CSRF-token POST for the user and group update_policy action (#8145)
-security#GHSA-2p3x-f5jm-rg6p: Break the View-Graphs to poller remote code execution chain (#8145)
-security#GHSA-x5pw-cg7j-mj4r: Run the bundled webhits poller script wc through a shell-free open (#8145)
-security#GHSA-9737-rqh3-h7fh: Escape interpolated names in raise_message across the UI (#8145)
-security#GHSA-9x9h-2577-9w86: Build the colordropdown autocomplete from nodes and text, not HTML strings (#8145)
-security#GHSA-h96j-8xhc-2p3w: Authorize remote_agent on the genuine peer address, not forwarded headers (#8145)
-security: Validate host_id before it is concatenated into the graph_view list and preview filter WHERE clauses (GHSA-r7hc-hrpv-52gf) (#8100) - Special Thanks to Jiecub3, Aur0ra-m and lz2y
-security: Validate and bind local_graph_id in the aggregate graph item sequence query (GHSA-6mjm-5vwr-3fr2) (#8099) - Special Thanks to Jiecub3, Aur0ra-m and lz2y
-security: Grant AllowOverride All in docker/apache.conf so shipped .htaccess denies on log/cache/scripts/cli take effect (GHSA-fxfg-j995-j69j)
-security: Authorize the bulk Change Data Source Profile action against the owning device (GHSA-fc82-w6xq-4jg7)
-security: Authorize Data Source enable/disable against the owning device before mutating (GHSA-2fhv-c794-v433)
-security: Confine Reports format_file to a bare filename to close a path traversal/LFI regression (GHSA-5x27-wqpm-m24v)
-security: Reject ORDER BY sort_column subquery payloads that bypassed the GHSA-q9xg-p762-9jm3 fix (GHSA-8j73-cvf6-jrvx)
-security: Authorize Report save/edit against report ownership to close an authenticated IDOR (GHSA-8f5c-3h59-q7gc)
-security: Stop building the Realtime RRD create command through a shell and validate DS bounds are numeric before they reach it (GHSA-f88m-q789-g22j)
-security: Authorize tree node create/delete/move/rename/copy against per-tree access before mutating (GHSA-prxj-84qq-v5jq)
-security: Authorize single-item Report actions (remove/move) against report ownership to close a guest-bind IDOR (GHSA-j5jh-fhwg-r56x)
-security: Use validate_redirect_url() for the CSRF timeout redirect to close a tab-based open redirect bypass (GHSA-c725-4jm5-9fx5)
-security: Require Package Management permission to trust new package signers (GHSA-gxgm-8rhv-r7jv)
-security: Harden cmd.exe shell sinks and strip %VAR% from hostnames on win32 (GHSA-rjvj-r52f-8v5q) (#8056)
-security#GHSA-77pr-g949-4v5f: Authorize the target graph before Spike Kill rewrites its RRD history (#8141)
-security#GHSA-w3qw-762w-6g9v: Reject array-form GET actions that bypass the POST and CSRF guard (#8141)
-security#GHSA-xhpr-w454-cc9w: Cast the stored data-query output_type before building the poller cache query (#8141)
+3 -3
View File
@@ -768,11 +768,11 @@ function sync_color_templates(int $color_template) : void {
}
if ($failed > 0) {
raise_message('color_template_sync', __('Color Template \'%s\' failed to push out %d Aggregate Templates or Graphs', $name, $failed), MESSAGE_LEVEL_ERROR);
raise_message('color_template_sync', __esc('Color Template \'%s\' failed to push out %d Aggregate Templates or Graphs', $name, $failed), MESSAGE_LEVEL_ERROR);
} elseif ($found) {
raise_message('color_template_sync', __('Color Template \'%s\' had %d Aggregate Templates pushed out and %d Non-Templated Aggregates pushed out', $name, $templates, $graphs), MESSAGE_LEVEL_INFO);
raise_message('color_template_sync', __esc('Color Template \'%s\' had %d Aggregate Templates pushed out and %d Non-Templated Aggregates pushed out', $name, $templates, $graphs), MESSAGE_LEVEL_INFO);
} else {
raise_message('color_template_sync', __('Color Template \'%s\' had no Aggregate Templates or Graphs using this Color Template.', $name, $templates, $graphs), MESSAGE_LEVEL_INFO);
raise_message('color_template_sync', __esc('Color Template \'%s\' had no Aggregate Templates or Graphs using this Color Template.', $name, $templates, $graphs), MESSAGE_LEVEL_INFO);
}
}
+2 -2
View File
@@ -274,7 +274,7 @@ function form_save() : void {
if (cacti_sizeof($data_template_fields)) {
foreach ($data_template_fields as $data_template_field) {
raise_message('data_template_rrd_' . $data_template_field['dtr_id'], __('Field "%s" is missing an Output Field. Select the Output Field associated with this Data Source, and press Save again.', $data_template_field['data_source_name']), MESSAGE_LEVEL_WARN);
raise_message('data_template_rrd_' . $data_template_field['dtr_id'], __esc('Field "%s" is missing an Output Field. Select the Output Field associated with this Data Source, and press Save again.', $data_template_field['data_source_name']), MESSAGE_LEVEL_WARN);
}
}
}
@@ -463,7 +463,7 @@ function form_actions() : void {
$php_binary = read_config_option('path_php_binary');
exec_background($php_binary, CACTI_PATH_CLI . '/rebuild_poller_cache.php --data-template-id=' . $selected_items[$i]);
raise_message('repopulate_' . $i, __('The Poller Cache operation has been launched in background for Data Template ID %d.', $selected_items[$i]), MESSAGE_LEVEL_INFO);
raise_message('repopulate_' . $i, __esc('The Poller Cache operation has been launched in background for Data Template ID %d.', $selected_items[$i]), MESSAGE_LEVEL_INFO);
}
}
}
+4 -4
View File
@@ -1246,9 +1246,9 @@ function form_actions() : void {
[$selected_items[$i]]);
if (isset($_SESSION['sess_gt_repairs']) && $_SESSION['sess_gt_repairs'] > 0) {
raise_message('gt_repair' . $selected_items[$i], __('Sync of Graph Template \'%s\' Resulted in %s Repairs!', $graph_template_name, $_SESSION['sess_gt_repairs']), MESSAGE_LEVEL_WARN);
raise_message('gt_repair' . $selected_items[$i], __esc('Sync of Graph Template \'%s\' Resulted in %s Repairs!', $graph_template_name, $_SESSION['sess_gt_repairs']), MESSAGE_LEVEL_WARN);
} else {
raise_message('gt_repair' . $selected_items[$i], __('Sync of Graph Template \'%s\' Resulted in no Repairs.', $graph_template_name), MESSAGE_LEVEL_INFO);
raise_message('gt_repair' . $selected_items[$i], __esc('Sync of Graph Template \'%s\' Resulted in no Repairs.', $graph_template_name), MESSAGE_LEVEL_INFO);
}
}
} elseif (grv('drp_action') == '5') { // resequence graphs with sequences off
@@ -1261,9 +1261,9 @@ function form_actions() : void {
[$selected_items[$i]]);
if (isset($_SESSION['sess_gt_repairs']) && $_SESSION['sess_gt_repairs'] > 0) {
raise_message('gt_repair' . $selected_items[$i], __('Sync of Graph Template \'%s\' Resulted in %s Repairs!', $graph_template_name, $_SESSION['sess_gt_repairs']), MESSAGE_LEVEL_WARN);
raise_message('gt_repair' . $selected_items[$i], __esc('Sync of Graph Template \'%s\' Resulted in %s Repairs!', $graph_template_name, $_SESSION['sess_gt_repairs']), MESSAGE_LEVEL_WARN);
} else {
raise_message('gt_repair' . $selected_items[$i], __('Sync of Graph Template \'%s\' Resulted in no Repairs.', $graph_template_name), MESSAGE_LEVEL_INFO);
raise_message('gt_repair' . $selected_items[$i], __esc('Sync of Graph Template \'%s\' Resulted in no Repairs.', $graph_template_name), MESSAGE_LEVEL_INFO);
}
}
}
+2 -2
View File
@@ -1462,10 +1462,10 @@ function form_actions() : void {
[$local_graph_id]);
if (api_graph_change_device($local_graph_id, $host_id)) {
raise_message('moved_' . $local_graph_id, __('Graph %s Moved to new Device', $title), MESSAGE_LEVEL_INFO);
raise_message('moved_' . $local_graph_id, __esc('Graph %s Moved to new Device', $title), MESSAGE_LEVEL_INFO);
$success++;
} else {
raise_message('notmoved_' . $local_graph_id, __('Graph %s not Moved. Device missing Data Query', $title), MESSAGE_LEVEL_WARN);
raise_message('notmoved_' . $local_graph_id, __esc('Graph %s not Moved. Device missing Data Query', $title), MESSAGE_LEVEL_WARN);
$failures++;
}
}
+2 -2
View File
@@ -212,7 +212,7 @@ function host_reindex() : void {
[$host_id]
);
raise_message('host_reindex', __('Device Reindex Completed in %0.2f seconds. There were %d items updated.', $total_time, $items), MESSAGE_LEVEL_INFO);
raise_message('host_reindex', __esc('Device Reindex Completed in %0.2f seconds. There were %d items updated.', $total_time, $items), MESSAGE_LEVEL_INFO);
}
function add_tree_names_to_actions_array() : void {
@@ -356,7 +356,7 @@ function form_actions() : void {
[grv('report_id')]
);
raise_message('reports_add_error', __('Unable to add some Devices to Report \'%s\'', $name), MESSAGE_LEVEL_WARN);
raise_message('reports_add_error', __esc('Unable to add some Devices to Report \'%s\'', $name), MESSAGE_LEVEL_WARN);
}
} elseif (grv('drp_action') == '1') { // delete
ini_set('max_execution_time', '-1');
+1 -1
View File
@@ -270,7 +270,7 @@ function form_actions() : void {
db_execute_prepared('DELETE FROM host_template_archive WHERE id = ?', [$id]);
raise_message('archives_removed_' . $id, __('The Device Template Archive %s has been removed.', $name), MESSAGE_LEVEL_INFO);
raise_message('archives_removed_' . $id, __esc('The Device Template Archive %s has been removed.', $name), MESSAGE_LEVEL_INFO);
}
} elseif (gnrv('drp_action') == 2) {
top_header();
+6 -2
View File
@@ -144,7 +144,9 @@ if ($auth_method == AUTH_METHOD_BASIC && !isset($_SESSION[SESS_USER_ID])) {
VALUES (?, ?, 1, ?, NOW())',
[$username, $current_user['id'], $_SESSION[SESS_CLIENT_ADDR]]);
return true;
// GHSA-4rmr-wvjq-qxc2: fall through to the per-page realm check below
// instead of returning, so a Basic Auth login still has its
// authorization verified for the requested page.
} else {
require_once(CACTI_PATH_BASE . '/auth_login.php');
}
@@ -199,7 +201,9 @@ if (isset($guest_account)) {
WHERE id = ?',
[$_SESSION[SESS_USER_ID]]);
return true;
// GHSA-4rmr-wvjq-qxc2: fall through to the per-page realm check below
// instead of returning, so the guest account's access to this page is
// authorized rather than assumed.
}
}
+10 -3
View File
@@ -5253,7 +5253,13 @@ $.widget('custom.dropcolor', {
if (hex != null) {
this.wrapper.find('#bgc').css('background-color', '#' + hex[1]);
}
this.input = $('<input class="ui-autocomplete-input ui-state-default ui-selectmenu-text" style="background:transparent;border:0px;padding:0px;padding-left:24px;margin-left:-24px" value="' + value + '">')
// GHSA-9x9h-2577-9w86: build the input as a node so a colour name cannot
// break out of the value attribute once the browser decodes the entities.
this.input = $('<input>', {
'class': 'ui-autocomplete-input ui-state-default ui-selectmenu-text',
style: 'background:transparent;border:0px;padding:0px;padding-left:24px;margin-left:-24px',
value: value
})
.appendTo(this.wrapper)
.on('click', function () {
$(this).autocomplete('search', '');
@@ -5273,8 +5279,9 @@ $.widget('custom.dropcolor', {
$(this).data('ui-autocomplete')._renderItem = function (ul, item) {
var regExp = /\(([^)]+)\)/;
var hex = regExp.exec(item.label);
var mylabel = $($.parseHTML(item.label));
var label = mylabel.text();
// GHSA-9x9h-2577-9w86: item.label is plain text; drop the
// parseHTML round-trip that re-parses it as HTML.
var label = item.label;
if (hex !== null) {
color = hex[1];
+3 -3
View File
@@ -1194,7 +1194,7 @@ function display_matching_trees(int $rule_id, int $rule_type, array $item, strin
} else {
$sql_field = '"SQL Injection" AS source ';
cacti_log("Attempted SQL Injection found in Tree Automation for the field variable {$item['field']}.", false, 'AUTOM8');
raise_message('sql_injection', __("Attempted SQL Injection found in Tree Automation for the field variable {$item['field']}."), MESSAGE_LEVEL_ERROR);
raise_message('sql_injection', __esc("Attempted SQL Injection found in Tree Automation for the field variable {$item['field']}."), MESSAGE_LEVEL_ERROR);
}
// now we build up a new query for counting the rows
@@ -3397,7 +3397,7 @@ function create_all_header_nodes(int $item_id, array $rule) : int {
$target = db_fetch_cell($sql, '', false);
} else {
cacti_log("Attempted SQL Injection found in Tree Automation for the field variable {$tree_item['field']}.", false, 'AUTOM8');
raise_message('sql_injection', __("Attempted SQL Injection found in Tree Automation for the field variable {$tree_item['field']}."), MESSAGE_LEVEL_ERROR);
raise_message('sql_injection', __esc("Attempted SQL Injection found in Tree Automation for the field variable {$tree_item['field']}."), MESSAGE_LEVEL_ERROR);
$sql = '';
$target = '';
@@ -5342,7 +5342,7 @@ function automation_tree_rule_export(mixed $tree_rule_ids) : array {
[$rule_id]);
if (!cacti_sizeof($tree_rule)) {
raise_message('rule_missing', __('Can not find the Tree Rule with the ID %s', $rule_id), MESSAGE_LEVEL_ERROR);
raise_message('rule_missing', __esc('Can not find the Tree Rule with the ID %s', $rule_id), MESSAGE_LEVEL_ERROR);
return [];
}
+2 -2
View File
@@ -564,10 +564,10 @@ function api_data_source_change_host(array $data_sources, int $device_id) : void
if (($old_rcnn_id = poller_push_to_remote_db_connect($old_poller_id, true)) !== false) {
poller_item_delete_for_data_source($data_source, $old_rcnn_id, false);
} else {
raise_message('poller_down_' . $old_poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $old_poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $old_poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $old_poller_id), MESSAGE_LEVEL_WARN);
}
} else {
raise_message('poller_down_' . $old_poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $old_poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $old_poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $old_poller_id), MESSAGE_LEVEL_WARN);
}
}
+47 -47
View File
@@ -55,7 +55,7 @@ function api_device_remove(int $device_id) : void {
object_cache_get_totals('device_delete', $device_id);
if (!db_begin_transaction()) {
raise_message('device_remove_failed_' . $device_id, __('Unable to remove Device %s because a database transaction could not be started.', $device_id), MESSAGE_LEVEL_ERROR);
raise_message('device_remove_failed_' . $device_id, __esc('Unable to remove Device %s because a database transaction could not be started.', $device_id), MESSAGE_LEVEL_ERROR);
return;
}
@@ -78,7 +78,7 @@ function api_device_remove(int $device_id) : void {
if ($remaining_graphs === false || $remaining_graphs > 0) {
db_rollback_transaction();
raise_message('device_graph_remove_failed_' . $device_id, __('Unable to remove Device %s because Graph cleanup did not complete.', $device_id), MESSAGE_LEVEL_ERROR);
raise_message('device_graph_remove_failed_' . $device_id, __esc('Unable to remove Device %s because Graph cleanup did not complete.', $device_id), MESSAGE_LEVEL_ERROR);
return;
}
@@ -99,7 +99,7 @@ function api_device_remove(int $device_id) : void {
foreach ($cleanup_queries as [$sql, $params]) {
if (db_execute_prepared($sql, $params) === false) {
db_rollback_transaction();
raise_message('device_remove_failed_' . $device_id, __('Unable to remove Device %s because dependent database cleanup failed.', $device_id), MESSAGE_LEVEL_ERROR);
raise_message('device_remove_failed_' . $device_id, __esc('Unable to remove Device %s because dependent database cleanup failed.', $device_id), MESSAGE_LEVEL_ERROR);
return;
}
@@ -113,14 +113,14 @@ function api_device_remove(int $device_id) : void {
if ($removed === false) {
db_rollback_transaction();
raise_message('device_remove_failed_' . $device_id, __('Unable to remove Device %s because its primary database record could not be updated.', $device_id), MESSAGE_LEVEL_ERROR);
raise_message('device_remove_failed_' . $device_id, __esc('Unable to remove Device %s because its primary database record could not be updated.', $device_id), MESSAGE_LEVEL_ERROR);
return;
}
if (!db_commit_transaction()) {
db_rollback_transaction();
raise_message('device_remove_failed_' . $device_id, __('Unable to remove Device %s because its database transaction could not be committed.', $device_id), MESSAGE_LEVEL_ERROR);
raise_message('device_remove_failed_' . $device_id, __esc('Unable to remove Device %s because its database transaction could not be committed.', $device_id), MESSAGE_LEVEL_ERROR);
return;
}
@@ -178,10 +178,10 @@ function api_device_purge_from_remote(array|int $device_ids, int $poller_id = 0)
db_execute('DELETE FROM data_local WHERE ' . db_in_clause('host_id', $int_device_ids), true, $rcnn_id);
db_execute('DELETE FROM graph_local WHERE ' . db_in_clause('host_id', $int_device_ids), true, $rcnn_id);
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
foreach ($device_ids as $id) {
@@ -405,11 +405,11 @@ function api_device_disable_devices(array $device_ids) : void {
AND (deleted = '' OR (deleted = 'on' AND disabled = ''))",
[$device_id], true, $rcnn_id);
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
}
@@ -453,11 +453,11 @@ function api_device_enable_devices(array $device_ids) : void {
WHERE host_id = ?',
[$device_id], '', true, $rcnn_id);
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
@@ -500,11 +500,11 @@ function api_device_enable_devices(array $device_ids) : void {
if (($rcnn_id = poller_push_to_remote_db_connect($device_id)) !== false) {
poller_push_reindex_data_to_poller($device_id, 0, true, $rcnn_id);
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
}
@@ -568,11 +568,11 @@ function api_device_change_options(array $device_ids, array $post) : void {
AND deleted = ''",
[gnrv($field_name), $device_id], true, $rcnn_id);
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
}
@@ -617,11 +617,11 @@ function api_device_clear_statistics(array $device_ids) : void {
AND deleted = ''",
[$device_id], true, $rcnn_id);
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
}
@@ -674,10 +674,10 @@ function api_device_dq_add(int $device_id, int $data_query_id, string $reindex_m
VALUES (?, ?, ?)',
[$device_id, $data_query_id, $reindex_method], true, $rcnn_id);
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
}
@@ -728,10 +728,10 @@ function api_device_dq_remove(int $device_id, int $data_query_id) : void {
AND host_id = ?',
[$data_query_id, $device_id], true, $rcnn_id);
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
}
}
@@ -771,10 +771,10 @@ function api_device_dq_change(int $device_id, int $data_query_id, string $reinde
WHERE data_query_id = ?
AND host_id = ?', [$data_query_id, $device_id], true, $rcnn_id);
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
}
@@ -806,10 +806,10 @@ function api_device_gt_remove(int $device_id, int $graph_template_id) : void {
AND host_id = ?',
[$graph_template_id, $device_id], true, $rcnn_id);
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
}
}
@@ -1162,7 +1162,7 @@ function api_device_save(int $id, int $device_template_id, string $description,
if (remote_poller_up($previous_poller)) {
api_device_purge_from_remote($device_id, $previous_poller);
} else {
raise_message('poller_down_' . $save['id'], __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $previous_poller), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $save['id'], __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $previous_poller), MESSAGE_LEVEL_WARN);
$raised = true;
}
}
@@ -1175,11 +1175,11 @@ function api_device_save(int $id, int $device_template_id, string $description,
$save['id'] = $device_id;
sql_save($save, 'host', 'id', true, $rcnn_id);
} elseif (!$raised) {
raise_message('poller_down_' . $save['id'], __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $save['id'], __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised = true;
}
} elseif (!$raised) {
raise_message('poller_down_' . $save['id'], __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $save['id'], __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised = true;
}
}
@@ -1212,10 +1212,10 @@ function api_device_save(int $id, int $device_template_id, string $description,
WHERE host_id = ?',
[$device_id], true, $rcnn_id);
} elseif (!$raised) {
raise_message('poller_down_' . $save['id'], __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $save['id'], __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
} elseif (!$raised) {
raise_message('poller_down_' . $save['id'], __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $save['id'], __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
}
}
@@ -1407,11 +1407,11 @@ function api_device_update_host_template(int $device_id, int $device_template_id
AND deleted = ""',
[$device_template_id, $device_id], true, $rcnn_id);
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
}
@@ -1438,11 +1438,11 @@ function api_device_update_host_template(int $device_id, int $device_template_id
VALUES (?, ?, ?)',
[$device_id, $snmp_query['snmp_query_id'], read_config_option('reindex_method')], true, $rcnn_id);
} elseif ($raised[$poller_id]) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
}
@@ -1474,11 +1474,11 @@ function api_device_update_host_template(int $device_id, int $device_template_id
VALUES (?, ?)',
[$device_id, $graph_template['graph_template_id']], true, $rcnn_id);
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
}
@@ -1530,11 +1530,11 @@ function api_device_update_host_template(int $device_id, int $device_template_id
AND graph_template_id = ?',
[$device_id, $unused_graph_template['id']], true, $rcnn_id);
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
} elseif (!isset($raised[$poller_id])) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised[$poller_id] = true;
}
}
@@ -3381,7 +3381,7 @@ function api_device_template_archive_for_export(int $id) : mixed {
$success = package_template($xml_data, $info, $files, $debug);
if ($export_errors || !$success) {
raise_message('package_error_' . $id, __('There were errors packaging your Device Template: %s. Errors Follow. ', $info['name']) . str_replace("\n", '<br>', $debug), MESSAGE_LEVEL_ERROR);
raise_message('package_error_' . $id, __esc('There were errors packaging your Device Template: %s. Errors Follow. ', $info['name']) . str_replace("\n", '<br>', $debug), MESSAGE_LEVEL_ERROR);
return false;
}
@@ -3393,17 +3393,17 @@ function api_device_template_archive_for_export(int $id) : mixed {
return $output;
} else {
raise_message("package_error_$id", __('Unable to find Package file for Device Template: %s.', $info['name']), MESSAGE_LEVEL_ERROR);
raise_message("package_error_$id", __esc('Unable to find Package file for Device Template: %s.', $info['name']), MESSAGE_LEVEL_ERROR);
return false;
}
} else {
raise_message("export_failed_$id", __('The Export Failed for %s!. Check the Cacti Log for details', $info['name']), MESSAGE_LEVEL_ERROR);
raise_message("export_failed_$id", __esc('The Export Failed for %s!. Check the Cacti Log for details', $info['name']), MESSAGE_LEVEL_ERROR);
return false;
}
} else {
raise_message("export_failed_$id", __('Export Could not find the Device Template with the ID %s!. Check the Cacti Log for details', $id), MESSAGE_LEVEL_ERROR);
raise_message("export_failed_$id", __esc('Export Could not find the Device Template with the ID %s!. Check the Cacti Log for details', $id), MESSAGE_LEVEL_ERROR);
return false;
}
@@ -3464,7 +3464,7 @@ function api_device_template_archive(int $id, string $archive_note) : bool {
$success = package_template($xml_data, $info, $files, $debug);
if ($export_errors || !$success) {
raise_message('package_error_' . $id, __('There were errors packaging your Device Template: %s. Errors Follow. ', $info['name']) . str_replace("\n", '<br>', $debug), MESSAGE_LEVEL_ERROR);
raise_message('package_error_' . $id, __esc('There were errors packaging your Device Template: %s. Errors Follow. ', $info['name']) . str_replace("\n", '<br>', $debug), MESSAGE_LEVEL_ERROR);
return false;
}
@@ -3495,22 +3495,22 @@ function api_device_template_archive(int $id, string $archive_note) : bool {
]
);
raise_message("package_success_$id", __('The Device Template %s was Archived Successfully.', $info['name']), MESSAGE_LEVEL_INFO);
raise_message("package_success_$id", __esc('The Device Template %s was Archived Successfully.', $info['name']), MESSAGE_LEVEL_INFO);
unlink($package_file);
return true;
} else {
raise_message("package_error_$id", __('Unable to find Package file for Device Template: %s.', $info['name']), MESSAGE_LEVEL_ERROR);
raise_message("package_error_$id", __esc('Unable to find Package file for Device Template: %s.', $info['name']), MESSAGE_LEVEL_ERROR);
return false;
}
} else {
raise_message("export_failed_$id", __('The Export Failed for %s!. Check the Cacti Log for details', $info['name']), MESSAGE_LEVEL_ERROR);
raise_message("export_failed_$id", __esc('The Export Failed for %s!. Check the Cacti Log for details', $info['name']), MESSAGE_LEVEL_ERROR);
return false;
}
} else {
raise_message("export_failed_$id", __('Export Could not find the Device Template with the ID %s!. Check the Cacti Log for details', $id), MESSAGE_LEVEL_ERROR);
raise_message("export_failed_$id", __esc('Export Could not find the Device Template with the ID %s!. Check the Cacti Log for details', $id), MESSAGE_LEVEL_ERROR);
return false;
}
+5 -5
View File
@@ -136,19 +136,19 @@ function clog_purge_logfile(string $action = 'purge') : void {
// basic checking
if ($action == 'rotate' && $log_action == LOG_ACTION_PURGE) {
raise_message('rotate_failed', __('Cacti Log file rotation failed for Log File \'%s\'. User \'%s\' wished to rotate, but rotating is disabled', basename($purgefile), get_username()), MESSAGE_LEVEL_ERROR);
raise_message('rotate_failed', __esc('Cacti Log file rotation failed for Log File \'%s\'. User \'%s\' wished to rotate, but rotating is disabled', basename($purgefile), get_username()), MESSAGE_LEVEL_ERROR);
return;
}
if ($action == 'purge' && $log_action == LOG_ACTION_ROTATE) {
raise_message('purge_failed', __('Cacti Log file purging failed for Log File \'%s\'. User \'%s\' wished to purge, but purging is disabled', basename($purgefile), get_username()), MESSAGE_LEVEL_ERROR);
raise_message('purge_failed', __esc('Cacti Log file purging failed for Log File \'%s\'. User \'%s\' wished to purge, but purging is disabled', basename($purgefile), get_username()), MESSAGE_LEVEL_ERROR);
return;
}
if ($filename != $cactiLog && $filename != $errorLog && $action == 'rotate') {
raise_message('rotate_failed', __('Cacti Log file rotation failed for Log File \'%s\'. User \'%s\' wished to rotate, but rotating is not allowed on already rotated files', basename($purgefile), get_username()), MESSAGE_LEVEL_ERROR);
raise_message('rotate_failed', __esc('Cacti Log file rotation failed for Log File \'%s\'. User \'%s\' wished to rotate, but rotating is not allowed on already rotated files', basename($purgefile), get_username()), MESSAGE_LEVEL_ERROR);
return;
}
@@ -171,7 +171,7 @@ function clog_purge_logfile(string $action = 'purge') : void {
cacti_log($message, false, 'WEBUI');
} else {
raise_message('clog_removed', __('Removal Failed due to the Administrator blocking removal of archived files. The file \'%s\' can not be removed.', basename($purgefile)), MESSAGE_LEVEL_WARN);
raise_message('clog_removed', __esc('Removal Failed due to the Administrator blocking removal of archived files. The file \'%s\' can not be removed.', basename($purgefile)), MESSAGE_LEVEL_WARN);
}
} else {
if ($action == 'rotate') {
@@ -188,7 +188,7 @@ function clog_purge_logfile(string $action = 'purge') : void {
cacti_log($message, false, 'WEBUI');
} else {
raise_message('clog_removed', __('Unable to open log file \'%s\' for writing.', basename($logfile)), MESSAGE_LEVEL_ERROR);
raise_message('clog_removed', __esc('Unable to open log file \'%s\' for writing.', basename($logfile)), MESSAGE_LEVEL_ERROR);
}
}
} else {
+3 -3
View File
@@ -555,10 +555,10 @@ function data_query_remove_disabled_items(array $orphaned_ids) : void {
if (($rcnn_id = poller_push_to_remote_db_connect($poller_id, true)) !== false) {
poller_item_delete_for_data_source($orphaned_ids, $rcnn_id, false);
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
}
}
@@ -2953,7 +2953,7 @@ function api_data_query_errors(int $snmp_query_graph_id, array $post) : bool {
if (cacti_sizeof($data_sources)) {
foreach ($data_sources as $ds) {
if (!isset($post['dsdt_' . $ds['data_template_id'] . '_' . $ds['id'] . '_check'])) {
raise_message('mapping_error', __('You must select an XML output column for Data Source \'%s\' and toggle the checkbox to its right', $ds['data_source_name']), MESSAGE_LEVEL_ERROR);
raise_message('mapping_error', __esc('You must select an XML output column for Data Source \'%s\' and toggle the checkbox to its right', $ds['data_source_name']), MESSAGE_LEVEL_ERROR);
$errors = true;
}
+2 -2
View File
@@ -636,7 +636,7 @@ function set_config_option(string $config_name, mixed $value, bool $remote = fal
foreach ($pollers as $p => $t) {
if ($t > $gone_time) {
raise_message('poller_' . $p, __('Settings save to Data Collector %d skipped due to heartbeat.', $p), MESSAGE_LEVEL_WARN);
raise_message('poller_' . $p, __esc('Settings save to Data Collector %d skipped due to heartbeat.', $p), MESSAGE_LEVEL_WARN);
} else {
$rcnn_id = poller_connect_to_remote($p);
@@ -648,7 +648,7 @@ function set_config_option(string $config_name, mixed $value, bool $remote = fal
// check if we still have rcnn_id, if it's now become false, we had a problem
if (!$rcnn_id) {
raise_message('poller_' . $p, __('Settings save to Data Collector %d Failed.', $p), MESSAGE_LEVEL_ERROR);
raise_message('poller_' . $p, __esc('Settings save to Data Collector %d Failed.', $p), MESSAGE_LEVEL_ERROR);
}
}
}
+1 -1
View File
@@ -394,7 +394,7 @@ function reports_form_save() : void {
if ($regex_valid !== true) {
$_SESSION[SESS_ERROR_FIELDS]['graph_name_regexp'] = 3;
raise_message('custom', __('The regular expression "%s" is not valid. Error is %s', htmle((string) $save['graph_name_regexp']), htmle((string) $regex_valid)), MESSAGE_LEVEL_ERROR);
raise_message('custom', __esc('The regular expression "%s" is not valid. Error is %s', (string) $save['graph_name_regexp'], (string) $regex_valid), MESSAGE_LEVEL_ERROR);
}
}
$save['site_id'] = (isrv('site_id') ? form_input_validate(gnrv('site_id'), 'site_id', '^[-0-9]+$', true, 3) : 0);
+1 -1
View File
@@ -956,7 +956,7 @@ function get_filter_request_var(string $name, int $filter = FILTER_VALIDATE_INT,
if ($value === false) {
if ($filter == FILTER_VALIDATE_IS_REGEX) {
raise_message('custom', __('The regular expression "%s" is not valid. Error is %s', htmle((string) get_nfilter_request_var($name)), htmle((string) $custom_error)), MESSAGE_LEVEL_ERROR);
raise_message('custom', __esc('The regular expression "%s" is not valid. Error is %s', (string) get_nfilter_request_var($name), (string) $custom_error), MESSAGE_LEVEL_ERROR);
set_request_var($name, '');
} else {
die_html_input_error($name, get_nfilter_request_var($name));
+1 -1
View File
@@ -444,7 +444,7 @@ function process_paths(string $line, array $files, bool $raise_message) : array
if (cacti_sizeof($paths['missing_paths'])) {
if ($raise_message) {
foreach ($paths['missing_paths'] as $p) {
raise_message('missing_' . $p['file'], __('A Critical Template file \'%s\' is missing. Please locate this file before packaging', $p['file']), MESSAGE_LEVEL_ERROR);
raise_message('missing_' . $p['file'], __esc('A Critical Template file \'%s\' is missing. Please locate this file before packaging', $p['file']), MESSAGE_LEVEL_ERROR);
}
}
}
+25 -25
View File
@@ -758,11 +758,11 @@ function api_plugin_install(string $plugin) : bool {
$author = $info['author'];
$version = $info['version'];
} elseif (str_contains($plugin, 'plugin_')) {
raise_message('directory_error', __('The Plugin directory \'%s\' needs to be renamed to remove \'plugin_\' from the name before it can be installed.', $plugin), MESSAGE_LEVEL_ERROR);
raise_message('directory_error', __esc('The Plugin directory \'%s\' needs to be renamed to remove \'plugin_\' from the name before it can be installed.', $plugin), MESSAGE_LEVEL_ERROR);
return false;
} else {
raise_message('version_error', __('The Plugin in the directory \'%s\' does not include an version function \'%s()\'. This function must exist for the plugin to be installed.', $plugin, $function), MESSAGE_LEVEL_ERROR);
raise_message('version_error', __esc('The Plugin in the directory \'%s\' does not include an version function \'%s()\'. This function must exist for the plugin to be installed.', $plugin, $function), MESSAGE_LEVEL_ERROR);
return false;
}
@@ -796,7 +796,7 @@ function api_plugin_install(string $plugin) : bool {
cacti_log(sprintf('WARNING: Cacti Plugin %s was not installed by %s due to Configuration Issues', $plugin, get_username()), false, 'PLUGIN');
}
} else {
raise_message('install_error', __('The Plugin in the directory \'%s\' does not include an install function \'%s()\'. This function must exist for the plugin to be installed.', $plugin, $function), MESSAGE_LEVEL_ERROR);
raise_message('install_error', __esc('The Plugin in the directory \'%s\' does not include an install function \'%s()\'. This function must exist for the plugin to be installed.', $plugin, $function), MESSAGE_LEVEL_ERROR);
return false;
}
@@ -996,9 +996,9 @@ function api_plugin_remove_data(string $plugin) : void {
if (function_exists($rmdata_function)) {
$rmdata_function();
raise_message('rmdata_complete', __('Data for Plugin %s including Tables and Settings has been removed.', $plugin), MESSAGE_LEVEL_INFO);
raise_message('rmdata_complete', __esc('Data for Plugin %s including Tables and Settings has been removed.', $plugin), MESSAGE_LEVEL_INFO);
} else {
raise_message('rmdata_not_complete', __('Data for Plugin %s including Tables and Settings has not been removed due to missing removal function.', $plugin), MESSAGE_LEVEL_ERROR);
raise_message('rmdata_not_complete', __esc('Data for Plugin %s including Tables and Settings has not been removed due to missing removal function.', $plugin), MESSAGE_LEVEL_ERROR);
}
}
}
@@ -1472,7 +1472,7 @@ function api_plugin_archive_remove(string $plugin, string $id) : void {
WHERE plugin = ? AND id = ?',
[$plugin, $id]);
raise_message('plugin_archive_removed', __('The Archive for Plugin \'%s\' has been removed.', $plugin), MESSAGE_LEVEL_INFO);
raise_message('plugin_archive_removed', __esc('The Archive for Plugin \'%s\' has been removed.', $plugin), MESSAGE_LEVEL_INFO);
}
function api_plugin_archive_restore(string $plugin, string $id, string $type = 'archive') : bool {
@@ -1522,9 +1522,9 @@ function api_plugin_archive_restore(string $plugin, string $id, string $type = '
if (!is_dir($restore_path)) {
if (!mkdir($restore_path, 0755, true)) {
if ($type == 'archive') {
raise_message('restore_failed', __('Restore failed! The Plugin \'%s\' archive Restore failed. Unable to create directory \'%s\'.', $plugin, $restore_path), MESSAGE_LEVEL_ERROR);
raise_message('restore_failed', __esc('Restore failed! The Plugin \'%s\' archive Restore failed. Unable to create directory \'%s\'.', $plugin, $restore_path), MESSAGE_LEVEL_ERROR);
} else {
raise_message('restore_failed', __('Restore failed! The available Plugin \'%s\' Load failed. Unable to create directory \'%s\'.', $plugin, $restore_path), MESSAGE_LEVEL_ERROR);
raise_message('restore_failed', __esc('Restore failed! The available Plugin \'%s\' Load failed. Unable to create directory \'%s\'.', $plugin, $restore_path), MESSAGE_LEVEL_ERROR);
}
$archive->__destruct();
@@ -1636,9 +1636,9 @@ function api_plugin_archive_restore(string $plugin, string $id, string $type = '
if (basename($rfile) != $rfile) {
if (!is_dir(dirname($rfile)) && !mkdir(dirname($rfile), 0755, true)) {
if ($type == 'archive') {
raise_message('restore_failed', __('Restore failed! The archived Plugin \'%s\' Restore failed. Unable to create directory %s', $plugin, dirname($basefile)), MESSAGE_LEVEL_INFO);
raise_message('restore_failed', __esc('Restore failed! The archived Plugin \'%s\' Restore failed. Unable to create directory %s', $plugin, dirname($basefile)), MESSAGE_LEVEL_INFO);
} else {
raise_message('restore_failed', __('Load failed! The available Plugin \'%s\' Load failed. Unable to create directory %s', $plugin, dirname($basefile)), MESSAGE_LEVEL_INFO);
raise_message('restore_failed', __esc('Load failed! The available Plugin \'%s\' Load failed. Unable to create directory %s', $plugin, dirname($basefile)), MESSAGE_LEVEL_INFO);
}
$archive->__destruct();
@@ -1658,14 +1658,14 @@ function api_plugin_archive_restore(string $plugin, string $id, string $type = '
unlink($tmpfile);
if ($type == 'archive') {
raise_message('archive_restored', __('Restore succeeded! The archived Plugin \'%s\' Restore succeeded.', $plugin), MESSAGE_LEVEL_INFO);
raise_message('archive_restored', __esc('Restore succeeded! The archived Plugin \'%s\' Restore succeeded.', $plugin), MESSAGE_LEVEL_INFO);
db_execute_prepared('UPDATE plugin_config
SET last_updated = ?
WHERE directory = ?',
[$new_updated, $plugin]);
} else {
raise_message('archive_restored', __('Load succeeded! The available Plugin \'%s\' Load succeeded.', $plugin), MESSAGE_LEVEL_INFO);
raise_message('archive_restored', __esc('Load succeeded! The available Plugin \'%s\' Load succeeded.', $plugin), MESSAGE_LEVEL_INFO);
if ($id == 'develop') {
db_execute_prepared('UPDATE plugin_config
@@ -1683,18 +1683,18 @@ function api_plugin_archive_restore(string $plugin, string $id, string $type = '
return true;
} else {
if ($type == 'archive') {
raise_message('archive_failed', __('Restore failed! The archived Plugin \'%s\' Restore failed. Check the cacti.log for warnings.', $plugin), MESSAGE_LEVEL_ERROR);
raise_message('archive_failed', __esc('Restore failed! The archived Plugin \'%s\' Restore failed. Check the cacti.log for warnings.', $plugin), MESSAGE_LEVEL_ERROR);
} else {
raise_message('archive_failed', __('Load failed! The available Plugin \'%s\' Load failed. Check the cacti.log for warnings.', $plugin), MESSAGE_LEVEL_ERROR);
raise_message('archive_failed', __esc('Load failed! The available Plugin \'%s\' Load failed. Check the cacti.log for warnings.', $plugin), MESSAGE_LEVEL_ERROR);
}
return false;
}
} else {
if ($type == 'archive') {
raise_message('plugin_archive_not_found', __('Restore failed! Unable to locate the archive record for Plugin \'%s\' in the database.', $plugin), MESSAGE_LEVEL_ERROR);
raise_message('plugin_archive_not_found', __esc('Restore failed! Unable to locate the archive record for Plugin \'%s\' in the database.', $plugin), MESSAGE_LEVEL_ERROR);
} else {
raise_message('plugin_archive_not_found', __('Load failed! Unable to locate the available record for Plugin \'%s\' in the database.', $plugin), MESSAGE_LEVEL_ERROR);
raise_message('plugin_archive_not_found', __esc('Load failed! Unable to locate the available record for Plugin \'%s\' in the database.', $plugin), MESSAGE_LEVEL_ERROR);
}
return false;
@@ -1763,12 +1763,12 @@ function api_plugin_archive(string $plugin, string $note = '') : void {
unlink($tmpafile);
raise_message('plugin_archived', __('The Plugin \'%s\' has been archived successfully.', $plugin), MESSAGE_LEVEL_INFO);
raise_message('plugin_archived', __esc('The Plugin \'%s\' has been archived successfully.', $plugin), MESSAGE_LEVEL_INFO);
} else {
raise_message('plugin_archive_failed', __('The Plugin \'%s\' archiving process has failed. Check the Cacti log for errors.', $plugin), MESSAGE_LEVEL_ERROR);
raise_message('plugin_archive_failed', __esc('The Plugin \'%s\' archiving process has failed. Check the Cacti log for errors.', $plugin), MESSAGE_LEVEL_ERROR);
}
} else {
raise_message('plugin_archive_failed', __('The Plugin \'%s\' archiving process has failed due to the plugin directory being missing.', $plugin), MESSAGE_LEVEL_ERROR);
raise_message('plugin_archive_failed', __esc('The Plugin \'%s\' archiving process has failed due to the plugin directory being missing.', $plugin), MESSAGE_LEVEL_ERROR);
}
}
@@ -2063,7 +2063,7 @@ function plugin_fetch_latest_plugins() : mixed {
if ($details === false) {
if (CACTI_WEB) {
raise_message('releases_warning', __('The Cacti plugin %s has no releases.', $plugin_name), MESSAGE_LEVEL_WARN);
raise_message('releases_warning', __esc('The Cacti plugin %s has no releases.', $plugin_name), MESSAGE_LEVEL_WARN);
header('Location: plugins.php');
exit;
@@ -2143,7 +2143,7 @@ function plugin_fetch_latest_plugins() : mixed {
if ($file_details === false) {
if (CACTI_WEB) {
raise_message('plugins_failed', __('Unable to get %s from GitHub/GitLab location.', $file), MESSAGE_LEVEL_ERROR);
raise_message('plugins_failed', __esc('Unable to get %s from GitHub/GitLab location.', $file), MESSAGE_LEVEL_ERROR);
header('Location: plugins.php');
exit;
@@ -2213,7 +2213,7 @@ function plugin_fetch_latest_plugins() : mixed {
if ($develop === false) {
if (CACTI_WEB) {
raise_message('plugins_failed', __('Unable to get develop repo data for plugin %s from GitHub/GitLab location.', $plugin_name), MESSAGE_LEVEL_ERROR);
raise_message('plugins_failed', __esc('Unable to get develop repo data for plugin %s from GitHub/GitLab location.', $plugin_name), MESSAGE_LEVEL_ERROR);
header('Location: plugins.php');
exit;
@@ -2288,7 +2288,7 @@ function plugin_fetch_latest_plugins() : mixed {
if ($file_details === false) {
if (CACTI_WEB) {
raise_message('plugins_failed', __('Unable to get %s from GitHub/GitLab location.', $file), MESSAGE_LEVEL_ERROR);
raise_message('plugins_failed', __esc('Unable to get %s from GitHub/GitLab location.', $file), MESSAGE_LEVEL_ERROR);
header('Location: plugins.php');
exit;
@@ -2361,9 +2361,9 @@ function plugin_fetch_latest_plugins() : mixed {
$updated_plugins = $updated;
if (cacti_sizeof($avail_plugins)) {
raise_message('plugins_fetched', __('There were \'%s\' Plugins found at The Cacti Groups GitHub site and \'%s\' Plugins Tags/Releases were retrieved and updated in %0.2f seconds.', $total_plugins, $updated_plugins, $end - $start), MESSAGE_LEVEL_INFO);
raise_message('plugins_fetched', __esc('There were \'%s\' Plugins found at The Cacti Groups GitHub site and \'%s\' Plugins Tags/Releases were retrieved and updated in %0.2f seconds.', $total_plugins, $updated_plugins, $end - $start), MESSAGE_LEVEL_INFO);
} else {
raise_message('plugins_fetched', __('Unable to reach The Cacti Groups GitHub site. No plugin data retrieved in %0.2f seconds.', $end - $start), MESSAGE_LEVEL_WARN);
raise_message('plugins_fetched', __esc('Unable to reach The Cacti Groups GitHub site. No plugin data retrieved in %0.2f seconds.', $end - $start), MESSAGE_LEVEL_WARN);
}
cacti_log(sprintf('PLUGIN STATS: Time:%0.2f Plugins:%d Updated:%d', $end - $start, cacti_sizeof($avail_plugins), $updated_plugins), false, 'SYSTEM');
+5 -5
View File
@@ -172,14 +172,14 @@ function reports_add_devices(int $report_id, array $device_ids, array $timespan,
]
);
raise_message('reports_add_device_' . $device_id, __('Device \'%s\' successfully added to Report.', $description), MESSAGE_LEVEL_INFO);
raise_message('reports_add_device_' . $device_id, __esc('Device \'%s\' successfully added to Report.', $description), MESSAGE_LEVEL_INFO);
} else {
$errors++;
raise_message('reports_device_not_found', __('Device not found! Unable to add to Report'), MESSAGE_LEVEL_ERROR);
}
} else {
$errors++;
raise_message('reports_no_add_device_' . $device_id, __('Device \'%s\' not added to Report as it already exists on report.', $description), MESSAGE_LEVEL_WARN);
raise_message('reports_no_add_device_' . $device_id, __esc('Device \'%s\' not added to Report as it already exists on report.', $description), MESSAGE_LEVEL_WARN);
}
}
@@ -879,9 +879,9 @@ function reports_remove_history(int $history_id, int $report_id = 0) : void {
if (is_reports_admin() || $report['user_id'] == SESS_USER_ID) {
db_execute_prepared('DELETE FROM reports_log WHERE id = ?', [$history_id]);
raise_message('remove_message', __('Report \'%s\' History Removed by user \'%s\' or a Report Administrator can remove the report.', $report['name'], get_username($_SESSION[SESS_USER_ID])), MESSAGE_LEVEL_INFO);
raise_message('remove_message', __esc('Report \'%s\' History Removed by user \'%s\' or a Report Administrator can remove the report.', $report['name'], get_username($_SESSION[SESS_USER_ID])), MESSAGE_LEVEL_INFO);
} else {
raise_message('remove_error', __('Only the owning user \'%s\' or a Report Administrator can remove the report.', get_username($_SESSION[SESS_USER_ID])), MESSAGE_LEVEL_ERROR);
raise_message('remove_error', __esc('Only the owning user \'%s\' or a Report Administrator can remove the report.', get_username($_SESSION[SESS_USER_ID])), MESSAGE_LEVEL_ERROR);
}
}
@@ -2387,7 +2387,7 @@ function reports_queue(string $name, int $request_type, string $source, int $sou
}
} else {
if ($requested_id > 0) {
raise_message('report_not_scheduled', __("The Report '%s' from source %s with id %s was not scheduled to run due to an error!", $name, $source, $source_id, 'flowview'), MESSAGE_LEVEL_ERROR);
raise_message('report_not_scheduled', __esc("The Report '%s' from source %s with id %s was not scheduled to run due to an error!", $name, $source, $source_id, 'flowview'), MESSAGE_LEVEL_ERROR);
} else {
cacti_log(sprintf("FATAL: The Report '%s' from source %s with id %s was not scheduled to run due to an error!", $name, $source, $source_id), false, 'REPORTS');
}
+2 -2
View File
@@ -1616,10 +1616,10 @@ function data_source_to_data_template(int $local_data_id, string $data_source_ti
if (($rcnn_id = poller_push_to_remote_db_connect($poller_id, true)) !== false) {
poller_item_delete_for_data_source($local_data_id, $rcnn_id, false);
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
}
}
+2 -2
View File
@@ -150,12 +150,12 @@ function process_user_input(array &$timespan, int $timeshift) : void {
$errors = 0;
if ($date1 < $early_date) {
raise_message('start_too_early', __('Your Start Date \'%s\' is before January 1993. Please pick a more recent Start Date.', date('Y-m-d H:i:s', (int) $date1)), MESSAGE_LEVEL_WARN);
raise_message('start_too_early', __esc('Your Start Date \'%s\' is before January 1993. Please pick a more recent Start Date.', date('Y-m-d H:i:s', (int) $date1)), MESSAGE_LEVEL_WARN);
$errors++;
}
if ($date2 < $early_date) {
raise_message('start_too_early', __('Your End Date \'%s\' is before January 1993. Please pick a more recent End Date.', date('Y-m-d H:i:s', (int) $date2)), MESSAGE_LEVEL_WARN);
raise_message('start_too_early', __esc('Your End Date \'%s\' is before January 1993. Please pick a more recent End Date.', date('Y-m-d H:i:s', (int) $date2)), MESSAGE_LEVEL_WARN);
$errors++;
}
+8 -8
View File
@@ -669,11 +669,11 @@ function poller_update_poller_cache_from_buffer(array $local_data_ids, array &$p
AND local_data_id IN ($ids)",
[$poller_id], true, $rcnn_id);
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised = true;
}
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised = true;
}
}
@@ -750,11 +750,11 @@ function poller_update_poller_cache_from_buffer(array $local_data_ids, array &$p
if (($rcnn_id = poller_push_to_remote_db_connect($poller_id, true)) !== false) {
db_execute($sql_prefix . $buffer . $sql_suffix, true, $rcnn_id);
} elseif (!$raised) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised = true;
}
} elseif (!$raised) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised = true;
}
}
@@ -776,11 +776,11 @@ function poller_update_poller_cache_from_buffer(array $local_data_ids, array &$p
if (($rcnn_id = poller_push_to_remote_db_connect($poller_id, true)) !== false) {
db_execute($sql_prefix . $buffer . $sql_suffix, true, $rcnn_id);
} else {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised = true;
}
} elseif (!$raised) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
$raised = true;
}
}
@@ -803,10 +803,10 @@ function poller_update_poller_cache_from_buffer(array $local_data_ids, array &$p
AND local_data_id IN ($ids)",
[$poller_id], true, $rcnn_id);
} elseif (!$raised) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
} elseif (!$raised) {
raise_message('poller_down_' . $poller_id, __('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
raise_message('poller_down_' . $poller_id, __esc('Remote Poller %s is Down, you will need to perform a FullSync once it is up again', $poller_id), MESSAGE_LEVEL_WARN);
}
}
}
+10 -10
View File
@@ -214,7 +214,7 @@ function form_actions() : void {
if (!is_dir($tmp_dir)) {
if (!mkdir($tmp_dir, 0777, true)) {
raise_message('tmpdir_fail', __('Unable to create package temporary directory %s.', $tmp_dir), MESSAGE_LEVEL_ERROR);
raise_message('tmpdir_fail', __esc('Unable to create package temporary directory %s.', $tmp_dir), MESSAGE_LEVEL_ERROR);
header('Location: package_import.php?package_location=' . $package_location);
@@ -230,9 +230,9 @@ function form_actions() : void {
if ($data !== false && cacti_sizeof($data[0])) {
import_display_results($data[0], [], true, true);
raise_message('import_success_' . md5($xmlfile), __('The Package %s Imported Successfully', $name), MESSAGE_LEVEL_INFO);
raise_message('import_success_' . md5($xmlfile), __esc('The Package %s Imported Successfully', $name), MESSAGE_LEVEL_INFO);
} else {
raise_message('import_fail_' . md5($xmlfile), __('The Package %s Import Failed', $name), MESSAGE_LEVEL_ERROR);
raise_message('import_fail_' . md5($xmlfile), __esc('The Package %s Import Failed', $name), MESSAGE_LEVEL_ERROR);
}
unlink($xmlfile);
@@ -600,9 +600,9 @@ function form_save() : void {
import_display_package_data($templates, $files, $package_name, $xmlfile, $data, false);
} else {
if ($data !== false) {
raise_message('import_success_' . md5($xmlfile), __('The Package %s Imported Successfully', $package_name), MESSAGE_LEVEL_INFO);
raise_message('import_success_' . md5($xmlfile), __esc('The Package %s Imported Successfully', $package_name), MESSAGE_LEVEL_INFO);
} else {
raise_message('import_fail_' . md5($xmlfile), __('The Package %s Import Failed', $package_name), MESSAGE_LEVEL_ERROR);
raise_message('import_fail_' . md5($xmlfile), __esc('The Package %s Import Failed', $package_name), MESSAGE_LEVEL_ERROR);
}
unlink($xmlfile);
@@ -940,7 +940,7 @@ function package_accept_key() : void {
unlink($xmlfile);
} else {
raise_message('repo_missing', __('The Repo \'%s\' is NOT Reachable at the URL Location or the package.manifest file is missing.', $repo['name']), MESSAGE_LEVEL_WARN);
raise_message('repo_missing', __esc('The Repo \'%s\' is NOT Reachable at the URL Location or the package.manifest file is missing.', $repo['name']), MESSAGE_LEVEL_WARN);
header('Location: package_import.php');
exit;
@@ -2000,7 +2000,7 @@ function get_repo_file(string $repo_id, string $filename = 'package.manifest', b
}
if (!$javascript) {
raise_message('repo_missing', __('The Repo \'%s\' is NOT Reachable on GitHub or the \'%s\' file is missing or it could be an invalid branch. Valid Package Locations are normally: https://github.com/Author/RepoName/.', $repo['name'], $filename), MESSAGE_LEVEL_ERROR);
raise_message('repo_missing', __esc('The Repo \'%s\' is NOT Reachable on GitHub or the \'%s\' file is missing or it could be an invalid branch. Valid Package Locations are normally: https://github.com/Author/RepoName/.', $repo['name'], $filename), MESSAGE_LEVEL_ERROR);
}
} elseif ($repo['repo_type'] == 2) { // Direct URL
$file = $repo['repo_location'] . '/' . $filename;
@@ -2019,7 +2019,7 @@ function get_repo_file(string $repo_id, string $filename = 'package.manifest', b
}
if (!$javascript) {
raise_message('repo_missing', __('The Repo \'%s\' is NOT Reachable at the URL Location or the package.manifest file is missing.', $repo['name']), MESSAGE_LEVEL_ERROR);
raise_message('repo_missing', __esc('The Repo \'%s\' is NOT Reachable at the URL Location or the package.manifest file is missing.', $repo['name']), MESSAGE_LEVEL_ERROR);
}
} else { // Server Directory
$file = $repo['repo_location'] . '/' . $filename;
@@ -2032,10 +2032,10 @@ function get_repo_file(string $repo_id, string $filename = 'package.manifest', b
}
if (!$javascript) {
raise_message('repo_exists', __('The Repo \'%s\' is Reachable on the Local Cacti Server. But not data returned from the manifest file.', $repo['name']), MESSAGE_LEVEL_ERROR);
raise_message('repo_exists', __esc('The Repo \'%s\' is Reachable on the Local Cacti Server. But not data returned from the manifest file.', $repo['name']), MESSAGE_LEVEL_ERROR);
}
} elseif (!$javascript) {
raise_message('repo_missing', __('The Repo \'%s\' is NOT Reachable on the Local Cacti Server or the package.manifest file is missing.', $repo['name']), MESSAGE_LEVEL_ERROR);
raise_message('repo_missing', __esc('The Repo \'%s\' is NOT Reachable on the Local Cacti Server or the package.manifest file is missing.', $repo['name']), MESSAGE_LEVEL_ERROR);
}
}
}
+6 -6
View File
@@ -119,9 +119,9 @@ function form_save() : void {
$data = file_get_contents($file, false, $context);
if ($data != '') {
raise_message('repo_exists', __('The Repo \'%s\' is Reachable on GitHub.', $save['name']), MESSAGE_LEVEL_INFO);
raise_message('repo_exists', __esc('The Repo \'%s\' is Reachable on GitHub.', $save['name']), MESSAGE_LEVEL_INFO);
} else {
raise_message('repo_missing', __('The Repo \'%s\' is NOT Reachable on GitHub or the package.manifest file is missing or it could be an invalid branch. Valid Package Locations are normally: https://github.com/Author/RepoName/.', $save['name']), MESSAGE_LEVEL_WARN);
raise_message('repo_missing', __esc('The Repo \'%s\' is NOT Reachable on GitHub or the package.manifest file is missing or it could be an invalid branch. Valid Package Locations are normally: https://github.com/Author/RepoName/.', $save['name']), MESSAGE_LEVEL_WARN);
}
} elseif ($save['repo_type'] == 2) {
$file = $save['repo_location'] . '/package.manifest';
@@ -136,17 +136,17 @@ function form_save() : void {
$data = file_get_contents($file, false, stream_context_create($context));
if ($data != '') {
raise_message('repo_exists', __('The Repo \'%s\' is Reachable at the URL Location.', $save['name']), MESSAGE_LEVEL_INFO);
raise_message('repo_exists', __esc('The Repo \'%s\' is Reachable at the URL Location.', $save['name']), MESSAGE_LEVEL_INFO);
} else {
raise_message('repo_missing', __('The Repo \'%s\' is NOT Reachable at the URL Location or the package.manifest file is missing.', $save['name']), MESSAGE_LEVEL_WARN);
raise_message('repo_missing', __esc('The Repo \'%s\' is NOT Reachable at the URL Location or the package.manifest file is missing.', $save['name']), MESSAGE_LEVEL_WARN);
}
} else {
$file = $save['repo_location'] . '/package.manifest';
if (file_exists($file)) {
raise_message('repo_exists', __('The Repo \'%s\' is Reachable on the Local Cacti Server.', $save['name']), MESSAGE_LEVEL_INFO);
raise_message('repo_exists', __esc('The Repo \'%s\' is Reachable on the Local Cacti Server.', $save['name']), MESSAGE_LEVEL_INFO);
} else {
raise_message('repo_missing', __('The Repo \'%s\' is NOT Reachable on the Local Cacti Server or the package.manifest file is missing.', $save['name']), MESSAGE_LEVEL_WARN);
raise_message('repo_missing', __esc('The Repo \'%s\' is NOT Reachable on the Local Cacti Server or the package.manifest file is missing.', $save['name']), MESSAGE_LEVEL_WARN);
}
}
+6 -6
View File
@@ -164,14 +164,14 @@ if (isrv('plugin')) {
$display_action = ucwords(str_replace('_', ' ', $action));
if (!in_array($plugin, $pluginslist, true) && !in_array($action, $safe_actions, true)) {
raise_message('invalid_plugin', __('The action \'%s\' on Plugin \'%s\' can not be performed due to the Plugin in it\'s current state.', $display_action, $plugin), MESSAGE_LEVEL_ERROR);
raise_message('invalid_plugin', __esc('The action \'%s\' on Plugin \'%s\' can not be performed due to the Plugin in it\'s current state.', $display_action, $plugin), MESSAGE_LEVEL_ERROR);
header('Location: plugins.php');
exit;
}
if (in_array($plugin, $plugins_integrated, true)) {
raise_message('invalid_plugin_action', __('The action \'%s\' \'%s\' on Plugin \'%s\' can not be taken as the Plugin is integrated.', $display_action, $plugin), MESSAGE_LEVEL_ERROR);
raise_message('invalid_plugin_action', __esc('The action \'%s\' on Plugin \'%s\' can not be taken as the Plugin is integrated.', $display_action, $plugin), MESSAGE_LEVEL_ERROR);
header('Location: plugins.php');
exit;
@@ -267,7 +267,7 @@ switch($action) {
depended-upon plugin (which would run its uninstall hook and drop its
tables without the intended confirmation). */
if (is_dir(CACTI_PATH_PLUGINS . '/' . $plugin)) {
raise_message('force_remove_present', __('Plugin \'%s\' can not be Force Uninstalled because its directory is still present. Use the normal Uninstall action instead.', $plugin), MESSAGE_LEVEL_ERROR);
raise_message('force_remove_present', __esc('Plugin \'%s\' can not be Force Uninstalled because its directory is still present. Use the normal Uninstall action instead.', $plugin), MESSAGE_LEVEL_ERROR);
header('Location: plugins.php');
@@ -281,7 +281,7 @@ switch($action) {
['%' . $plugin . '%']);
if ($required != '') {
raise_message('force_remove_required', __('Plugin \'%s\' can not be Force Uninstalled because it is still required by: \'%s\'', $plugin, ucfirst($required)), MESSAGE_LEVEL_ERROR);
raise_message('force_remove_required', __esc('Plugin \'%s\' can not be Force Uninstalled because it is still required by: \'%s\'', $plugin, ucfirst($required)), MESSAGE_LEVEL_ERROR);
header('Location: plugins.php');
@@ -328,9 +328,9 @@ switch($action) {
WHERE directory = ?',
[$plugin]);
raise_message('plugin_good', __('Plugin \'%s\' has passed it\'s Configuration Check test and can not be Installed', $plugin), MESSAGE_LEVEL_INFO);
raise_message('plugin_good', __esc('Plugin \'%s\' has passed it\'s Configuration Check test and can not be Installed', $plugin), MESSAGE_LEVEL_INFO);
} elseif ($response === null) {
raise_message('plugin_good', __('Plugin \'%s\' Check Configuration function returned a null response which is invalid. Please check with Plugin Developer for an update.', $plugin), MESSAGE_LEVEL_WARN);
raise_message('plugin_good', __esc('Plugin \'%s\' Check Configuration function returned a null response which is invalid. Please check with Plugin Developer for an update.', $plugin), MESSAGE_LEVEL_WARN);
}
header('Location: plugins.php');
+5 -2
View File
@@ -128,8 +128,11 @@ function debug(string $message) : void {
function remote_client_authorized() : bool {
global $poller_db_cnn_id, $remote_agent_whitelist;
// don't allow to run from the command line
$client_addr = get_client_addr();
// GHSA-h96j-8xhc-2p3w: authorize on the genuine TCP peer, not get_client_addr(),
// which honours client-settable proxy headers (X-Forwarded-For, etc.). A remote
// data collector connects directly, so a forwarded header must never decide this
// check. A proxied deployment must list the proxy's own address as a poller.
$client_addr = $_SERVER['REMOTE_ADDR'] ?? false;
if ($client_addr === false) {
return false;
+4 -1
View File
@@ -9,7 +9,10 @@ if ($ARGV[0] eq "") {
$log_path = $ARGV[0];
}
open(PROCESS,"wc -l $log_path |");
# GHSA-x5pw-cg7j-mj4r: run wc through a list-form open with no shell, so a
# crafted log path cannot start a second shell and undo the argument escaping
# Cacti already applied to this field.
open(PROCESS, '-|', 'wc', '-l', '--', $log_path);
$webhits = <PROCESS>;
close(PROCESS);
$webhits =~ s/[\s]*([0-9]+).*//;
+2 -2
View File
@@ -1540,7 +1540,7 @@ function save_settings() : void {
foreach ($pollers as $p => $t) {
if ($t > $gone_time) {
raise_message('poller_' . $p, __('Settings save to Data Collector %d skipped due to heartbeat.', $p), MESSAGE_LEVEL_WARN);
raise_message('poller_' . $p, __esc('Settings save to Data Collector %d skipped due to heartbeat.', $p), MESSAGE_LEVEL_WARN);
} else {
$rcnn_id = poller_connect_to_remote($p);
@@ -1552,7 +1552,7 @@ function save_settings() : void {
// check if we still have rcnn_id, if it's now become false, we had a problem
if (!$rcnn_id) {
raise_message('poller_' . $p, __('Settings save to Data Collector %d Failed.', $p), MESSAGE_LEVEL_ERROR);
raise_message('poller_' . $p, __esc('Settings save to Data Collector %d Failed.', $p), MESSAGE_LEVEL_ERROR);
}
}
}
+3 -3
View File
@@ -63,7 +63,7 @@ function support_lockout() : void {
$admin = read_config_option('admin_user', true);
if ($admin != $_SESSION[SESS_USER_ID]) {
raise_message('lockout_user', __('Only the Primary Cacti Administrator \'%s\' can lockout the Cacti system.', get_username($admin)), MESSAGE_LEVEL_ERROR);
raise_message('lockout_user', __esc('Only the Primary Cacti Administrator \'%s\' can lockout the Cacti system.', get_username($admin)), MESSAGE_LEVEL_ERROR);
} else {
$status = read_config_option('cacti_lockout_status', true);
$is_locked = ($status != '');
@@ -79,11 +79,11 @@ function support_lockout() : void {
} elseif ($is_locked !== ($expected === 'locked')) {
raise_message('lockout', __('The Cacti maintenance lockout state was changed by another administrator since this page was loaded. Please review the current status and try again.'), MESSAGE_LEVEL_INFO);
} elseif (!$is_locked) {
raise_message('lockout', __('Cacti has been locked out by \'%s\'. Press the button again after Cacti maintenance is over.', get_username($admin)), MESSAGE_LEVEL_WARN);
raise_message('lockout', __esc('Cacti has been locked out by \'%s\'. Press the button again after Cacti maintenance is over.', get_username($admin)), MESSAGE_LEVEL_WARN);
cacti_log('WARNING: Cacti has been locked out by the primary administrator!');
set_config_option('cacti_lockout_status', json_encode(['session' => session_id(), 'time' => time()]));
} else {
raise_message('lockout', __('Cacti maintenance lockout has been cleared by \'%s\'. Press the button again after Cacti maintenance is over.', get_username($admin)), MESSAGE_LEVEL_INFO);
raise_message('lockout', __esc('Cacti maintenance lockout has been cleared by \'%s\'. Press the button again after Cacti maintenance is over.', get_username($admin)), MESSAGE_LEVEL_INFO);
cacti_log('WARNING: Cacti maintenance lockout has been cleared by the primary administrator!');
set_config_option('cacti_lockout_status', '');
}
@@ -0,0 +1,24 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/
/*
* GHSA-4rmr-wvjq-qxc2: include/auth.php returned true from the Basic Auth and
* guest branches before the per-page realm check. Both branches now fall
* through to the realm check.
*/
$root = dirname(__DIR__, 4);
test('the Basic Auth and guest branches fall through to the per-page realm check', function () use ($root) {
$source = file_get_contents($root . '/include/auth.php');
expect($source)->not->toContain("\$_SESSION[SESS_CLIENT_ADDR]]);\n\n\t\t\treturn true;")
->and($source)->not->toContain("[\$_SESSION[SESS_USER_ID]]);\n\n\t\treturn true;")
->and(substr_count($source, 'GHSA-4rmr-wvjq-qxc2'))->toBe(2);
});
@@ -0,0 +1,27 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/
/*
* GHSA-h96j-8xhc-2p3w: remote_agent.php authorized on get_client_addr(), which
* honours client-settable proxy headers. The check must use the genuine peer.
*/
$root = dirname(__DIR__, 4);
test('remote_agent authorizes on the genuine peer address, not forwarded headers', function () use ($root) {
$source = file_get_contents($root . '/remote_agent.php');
$start = strpos($source, 'function remote_client_authorized(');
expect($start)->not->toBeFalse();
$body = substr($source, $start, 1200);
expect($body)->toContain("\$client_addr = \$_SERVER['REMOTE_ADDR']")
->and($body)->not->toContain('$client_addr = get_client_addr();');
});
@@ -0,0 +1,36 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/
/*
* GHSA-j67j-wpm4-9g3x: the update_policy branch runs before the action
* dispatcher, so the global.php GET/CSRF denylist cannot cover it. Both
* user_admin.php and user_group_admin.php must require a POST before calling
* update_policies() (csrf_check() only validates the token on POST).
*/
$root = dirname(__DIR__, 4);
test('update_policy requires a POST before mutating the policy', function () use ($root) {
foreach (array('/user_admin.php', '/user_group_admin.php') as $file) {
$source = file_get_contents($root . $file);
$branch = strpos($source, "if (isrv('update_policy')) {");
$call = strpos($source, 'update_policies();', $branch);
$guard = strpos($source, "strtoupper(\$_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST'", $branch);
expect($branch)->not->toBeFalse()
->and($call)->not->toBeFalse()
->and($guard)->not->toBeFalse()
->and($guard)->toBeLessThan($call);
$pre = substr($source, $guard, $call - $guard);
expect($pre)->toContain('http_response_code(405)')
->and($pre)->toContain('exit;');
}
});
@@ -0,0 +1,23 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/
/*
* GHSA-x5pw-cg7j-mj4r / GHSA-2p3x-f5jm-rg6p: scripts/webhits.pl ran wc through
* a two-argument piped open(), re-opening a shell with the log path embedded.
* It now uses a list-form open with no shell.
*/
$root = dirname(__DIR__, 4);
test('webhits.pl runs wc through a list-form open with no shell', function () use ($root) {
$source = file_get_contents($root . '/scripts/webhits.pl');
expect($source)->toContain("open(PROCESS, '-|', 'wc', '-l', '--', \$log_path)")
->and($source)->not->toContain('open(PROCESS,"wc -l $log_path |")');
});
@@ -0,0 +1,28 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/
/*
* GHSA-9x9h-2577-9w86: the custom.dropcolor autocomplete built its input from
* an HTML string with a raw value and round-tripped the label through
* parseHTML. It now builds the input as a node and uses the label as text.
*/
$root = dirname(__DIR__, 4);
test('the colordropdown input is a node and the label is not re-parsed as HTML', function () use ($root) {
$source = file_get_contents($root . '/include/layout.js');
// input built as a node, not from a value="' + value + '" HTML string
expect($source)->toContain('value: value')
->and($source)->not->toContain('ui-selectmenu-text" style="background:transparent;border:0px;padding:0px;padding-left:24px;margin-left:-24px" value="\' + value + \'">')
// no parseHTML round-trip of the label
->and($source)->not->toContain('var mylabel = $($.parseHTML(item.label));')
// the label still reaches the DOM as text
->and($source)->toContain('document.createTextNode(label)');
});
@@ -0,0 +1,42 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/
/*
* GHSA-9737-rqh3-h7fh: names interpolated into raise_message() went through
* __() (no escaping) across many pages. Those sinks now use __esc(). A static
* URL in the message text does not exempt a line whose interpolated value still
* needs escaping. This asserts no name-bearing unescaped form remains in the
* swept files.
*/
$root = dirname(__DIR__, 4);
$files = array('/lib/api_device.php', '/host.php', '/lib/utility.php', '/package_repos.php', '/package_import.php');
test('no name-bearing raise_message(..., __(...$...)) remains in the swept files', function () use ($root, $files) {
foreach ($files as $file) {
$source = file_get_contents($root . $file);
foreach (explode("\n", $source) as $line) {
if (strpos($line, 'raise_message(') !== false
&& strpos($line, ', __(') !== false
&& strpos($line, '$') !== false
&& strpos($line, 'html_escape') === false
// messages that intentionally build an HTML anchor or issue a
// redirect are excluded, exactly as the conversion was; a static
// URL in display text is not a reason to skip escaping
&& preg_match('/<[a-zA-Z\/]|&[a-z]+;|&#/', $line) === 0
&& preg_match('/href|<a |url_path|Location:/', $line) === 0) {
expect($line)->toBe('__swept__:' . $file);
}
}
}
expect(true)->toBeTrue();
});
+9
View File
@@ -39,6 +39,15 @@ if (read_config_option('secpass_2fa_enabled') == 'on') {
set_default_action();
if (isrv('update_policy')) {
// GHSA-j67j-wpm4-9g3x: update_policy is read before the action dispatcher, so
// the global.php GET/CSRF denylist cannot cover it. csrf_check() only validates
// the token on POST, so require POST before rewriting the user's permission policy.
if (strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
header('Allow: POST');
http_response_code(405);
exit;
}
update_policies();
} else {
switch (grv('action')) {
+9
View File
@@ -158,6 +158,15 @@ $fields_user_group_edit = [
];
if (isrv('update_policy')) {
// GHSA-j67j-wpm4-9g3x: update_policy is read before the action dispatcher, so
// the global.php GET/CSRF denylist cannot cover it. csrf_check() only validates
// the token on POST, so require POST before rewriting the group's permission policy.
if (strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
header('Allow: POST');
http_response_code(405);
exit;
}
update_policies();
} else {
switch (grv('action')) {