Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
eb77d25
code review sweep
bmfmancini Jul 24, 2026
1dc34b2
Update audit.php
bmfmancini Jul 24, 2026
98c88f7
additional sweep
bmfmancini Jul 24, 2026
4660680
rename some columns to be more specific
bmfmancini Jul 24, 2026
6d3afb2
Support json for external logging
bmfmancini Jul 24, 2026
ab887ac
fix json formatting
bmfmancini Jul 24, 2026
6e27cc3
expand auditing coverage
bmfmancini Jul 24, 2026
d3fb6c5
remove file
bmfmancini Jul 24, 2026
ff37c63
update php version
bmfmancini Jul 24, 2026
bb8b4da
fix failing workflow
bmfmancini Jul 24, 2026
0baa006
Merge upstream/develop into feature/compliance-event-capture
bmfmancini Jul 24, 2026
6b697af
Seperate puge log permissions
bmfmancini Jul 25, 2026
77ddc4f
rename permissions
bmfmancini Jul 25, 2026
aba1684
clean up name
bmfmancini Jul 25, 2026
3b7b330
group permissions for audit
bmfmancini Jul 25, 2026
0c78634
simply permissions
bmfmancini Jul 25, 2026
3f243db
Add more reliable way to capture success/fail
bmfmancini Jul 25, 2026
7c3689d
fix version
bmfmancini Jul 25, 2026
faeb08f
Merge remote-tracking branch 'upstream/develop' into feature/complian…
bmfmancini Jul 25, 2026
6ce4a08
Add secure remote Syslog audit delivery
bmfmancini Jul 25, 2026
0bee6bf
Fix Syslog warning leakage in poller
bmfmancini Jul 25, 2026
973adce
Delete openspec/changes/add-evidence-integrity-governance directory
bmfmancini Jul 25, 2026
bc08d10
Include audit evidence in CEF records
bmfmancini Jul 25, 2026
7afbf6d
Merge remote-tracking branch 'upstream/develop' into feature/evidence…
bmfmancini Jul 25, 2026
42ab811
Add PHP code quality tooling (PSR-12, PHPStan, PHP-CS-Fixer)
bmfmancini Jul 25, 2026
b7b3d42
Apply PHP-CS-Fixer auto-formatting (Cacti ruleset)
bmfmancini Jul 25, 2026
f99106f
Add declare(strict_types=1) and PHP 8.1+ syntax test
bmfmancini Jul 25, 2026
d734b02
Remove strict_types (deferred until Cacti 1.3)
bmfmancini Jul 25, 2026
0d9f180
Add native PHP 8.1+ type annotations to all plugin functions
bmfmancini Jul 25, 2026
346b2fb
Fix PHPStan level 8 errors in plugin source files
bmfmancini Jul 25, 2026
10e2e44
Add code-quality CI workflow
bmfmancini Jul 25, 2026
0f6d08e
Drop PHP 8.1 support, pin symfony to ^7.0
bmfmancini Jul 25, 2026
be7faeb
Restore PHP 8.1 support
bmfmancini Jul 25, 2026
d58faa1
feat: add authentication and session auditing
bmfmancini Jul 26, 2026
9b12b97
fix syntax
bmfmancini Jul 26, 2026
ddba16c
Fix cleanup during uninstall
bmfmancini Jul 26, 2026
7b4b954
.
bmfmancini Jul 26, 2026
fc364d3
Persist syslog batch settings
bmfmancini Jul 26, 2026
1fd9807
Merge upstream develop into feature/auth-session-audit
bmfmancini Jul 28, 2026
16402ad
Address PR 64 review feedback
bmfmancini Jul 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.php]
indent_style = tab
indent_size = 4

[*.{js,sh}]
indent_style = tab
indent_size = 4

[*.{po,pot,mo}]
binary = true

[*.md]
trim_trailing_whitespace = false
89 changes: 89 additions & 0 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# +-------------------------------------------------------------------------+
# | Copyright (C) 2004-2026 The Cacti Group |
# | |
# | This program is free software; you can redistribute it and/or |
# | modify it under the terms of the GNU General Public License |
# | as published by the Free Software Foundation; either version 2 |
# | of the License, or (at your option) any later version. |
# | |
# | This program is distributed in the hope that it will be useful, |
# | but WITHOUT ANY WARRANTY; without even the implied warranty of |
# | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
# | GNU General Public License for more details. |
# +-------------------------------------------------------------------------+
# | Cacti: The Complete RRDtool-based Graphing Solution |
# +-------------------------------------------------------------------------+
# | This code is designed, written, and maintained by the Cacti Group. See |
# | about.php and/or the AUTHORS file for specific developer information. |
# +-------------------------------------------------------------------------+
# | http://www.cacti.net/ |
# +-------------------------------------------------------------------------+

name: Code Quality

on:
push:
branches:
- main
- develop
pull_request:
branches:
- main
- develop

jobs:
code-quality:
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
php: ['8.1', '8.2', '8.3', '8.4']

name: PHP ${{ matrix.php }} Code Quality

steps:
- name: Checkout audit Plugin
uses: actions/checkout@v4

- name: Install PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: intl, mbstring, dom, xml, json, sockets
coverage: none
ini-values: "memory_limit=512M"

- name: Check PHP version
run: php -v

- name: Validate composer.json
run: composer validate --strict

- name: Install Composer Dependencies
run: composer install --prefer-dist --no-progress --ignore-platform-reqs

- name: Check PHP Syntax
run: |
if find . -name '*.php' -not -path './vendor/*' -not -path './locales/*' -exec php -l {} \; 2>&1 | grep -iv 'no syntax errors detected'; then
echo "Syntax errors found!"
exit 1
fi

- name: Run PHP-CS-Fixer (dry-run)
run: vendor/bin/php-cs-fixer fix --dry-run --diff --config=./.php-cs-fixer.php --allow-unsupported-php-version=yes

- name: Run PHPStan
run: vendor/bin/phpstan analyse --memory-limit=512M --no-progress

- name: Run Pest Tests
if: ${{ matrix.php != '8.1' }}
run: vendor/bin/pest tests/Security --display-warnings

- name: Run Audit Security Helper Tests
run: |
php tests/security_functions_test.php
php tests/controller_security_test.php
php tests/syslog_queue_test.php
php tests/auth_audit_test.php
timeout 60 php tests/syslog_functions_test.php
111 changes: 109 additions & 2 deletions .github/workflows/plugin-ci-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
matrix:
php: ['8.4']
os: [ubuntu-latest]
cacti_branch: ['1.2.x', 'develop']

services:
mysql:
Expand All @@ -57,14 +58,14 @@ jobs:
--health-timeout=5s
--health-retries=3

name: PHP ${{ matrix.php }} Integration Test on ${{ matrix.os }}
name: PHP ${{ matrix.php }} Integration Test (Cacti ${{ matrix.cacti_branch }}) on ${{ matrix.os }}

steps:
- name: Checkout Cacti
uses: actions/checkout@v7
with:
repository: Cacti/cacti
ref: 1.2.x
ref: ${{ matrix.cacti_branch }}
path: cacti

- name: Checkout audit Plugin
Expand Down Expand Up @@ -195,6 +196,39 @@ jobs:
echo "Audit Syslog delivery queue table is missing"
exit 1
fi

AUTH_STATE_TABLE_COUNT=$(mysql -u cactiuser -p'cactiuser' -h 127.0.0.1 cacti -se "
SELECT COUNT(*)
FROM information_schema.tables
WHERE table_schema = 'cacti'
AND table_name = 'audit_user_log_state';
")
if [ "$AUTH_STATE_TABLE_COUNT" -ne 1 ]; then
echo "Authentication deduplication state table is missing"
exit 1
fi

AUTH_STATE_FK_COUNT=$(mysql -u cactiuser -p'cactiuser' -h 127.0.0.1 cacti -se "
SELECT COUNT(*)
FROM information_schema.table_constraints
WHERE constraint_schema = 'cacti'
AND table_name = 'audit_user_log_state'
AND constraint_type = 'FOREIGN KEY';
")
if [ "$AUTH_STATE_FK_COUNT" -ne 0 ]; then
echo "Authentication deduplication state must survive audit-log purges"
exit 1
fi

THROTTLE_SETTING_COUNT=$(mysql -u cactiuser -p'cactiuser' -h 127.0.0.1 cacti -se "
SELECT COUNT(*)
FROM settings
WHERE name = 'audit_brute_force_last_alert';
")
if [ "$THROTTLE_SETTING_COUNT" -ne 1 ]; then
echo "Brute-force throttle setting was not initialized"
exit 1
fi

- name: Check PHP Syntax for Plugin
run: |
Expand All @@ -211,6 +245,7 @@ jobs:
php tests/controller_security_test.php
php tests/syslog_functions_test.php
php tests/syslog_queue_test.php
php tests/auth_audit_test.php

- name: Run Cacti Poller
run: |
Expand Down Expand Up @@ -241,6 +276,58 @@ jobs:
cd ${{ github.workspace }}/cacti
sudo php cli/add_device.php --description=test --ip=1

- name: Exercise authentication ingestion
run: |
mysql -u cactiuser -p'cactiuser' -h 127.0.0.1 cacti -e "
INSERT INTO user_log (username, user_id, time, result, ip)
VALUES ('audit_ci_login', 0, NOW(), 0, '192.0.2.10')
ON DUPLICATE KEY UPDATE result = VALUES(result), ip = VALUES(ip);
"
cd ${{ github.workspace }}/cacti
sudo php poller.php --poller=1 --force --debug

AUTH_EVENT_COUNT=$(mysql -u cactiuser -p'cactiuser' -h 127.0.0.1 cacti -se "
SELECT COUNT(*)
FROM audit_log
WHERE event_type = 'cacti.auth.login.failed'
AND target_id = 'audit_ci_login';
")
AUTH_STATE_COUNT=$(mysql -u cactiuser -p'cactiuser' -h 127.0.0.1 cacti -se "
SELECT COUNT(*)
FROM audit_user_log_state
WHERE source_hash = SHA2(
CONCAT('audit_ci_login', '|', 0, '|', (
SELECT time FROM user_log
WHERE username = 'audit_ci_login' AND user_id = 0
ORDER BY time DESC LIMIT 1
)),
256
);
")

if [ "$AUTH_EVENT_COUNT" -ne 1 ] || [ "$AUTH_STATE_COUNT" -ne 1 ]; then
echo "Authentication ingestion did not atomically create one event and one state marker"
exit 1
fi

mysql -u cactiuser -p'cactiuser' -h 127.0.0.1 cacti -e "
DELETE FROM audit_log
WHERE event_type = 'cacti.auth.login.failed'
AND target_id = 'audit_ci_login';
"
sudo php poller.php --poller=1 --force --debug

REPLAYED_EVENT_COUNT=$(mysql -u cactiuser -p'cactiuser' -h 127.0.0.1 cacti -se "
SELECT COUNT(*)
FROM audit_log
WHERE event_type = 'cacti.auth.login.failed'
AND target_id = 'audit_ci_login';
")
if [ "$REPLAYED_EVENT_COUNT" -ne 0 ]; then
echo "Authentication source row was replayed after audit-log deletion"
exit 1
fi

- name: check audit log entries
run: |
cd ${{ github.workspace }}
Expand All @@ -256,3 +343,23 @@ jobs:
echo "Unexpected CLI request status: $CLI_STATUS"
exit 1
fi

- name: Verify plugin uninstall cleanup
run: |
cd ${{ github.workspace }}/cacti
sudo php cli/plugin_manage.php --plugin=audit --disable --uninstall

AUDIT_SETTING_COUNT=$(mysql -u cactiuser -p'cactiuser' -h 127.0.0.1 cacti -se "
SELECT COUNT(*) FROM settings WHERE LEFT(name, 6) = 'audit_';
")
AUDIT_TABLE_COUNT=$(mysql -u cactiuser -p'cactiuser' -h 127.0.0.1 cacti -se "
SELECT COUNT(*)
FROM information_schema.tables
WHERE table_schema = 'cacti'
AND table_name IN ('audit_log', 'audit_syslog_delivery', 'audit_user_log_state');
")

if [ "$AUDIT_SETTING_COUNT" -ne 0 ] || [ "$AUDIT_TABLE_COUNT" -ne 0 ]; then
echo "Audit plugin uninstall left settings or tables behind"
exit 1
fi
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,16 @@


locales/po/*.mo

# Composer
vendor/

# PHPStan
phpstan.cache/
.phpstan-baseline.neon.local

# PHP-CS-Fixer
.php-cs-fixer.cache

# Pest / PHPUnit
.phpunit.result.cache
Loading
Loading