From ae59aa3326424d42187e98cf5da4c1aec280cb3d Mon Sep 17 00:00:00 2001 From: Marcus Hill Date: Sun, 2 Mar 2025 10:12:47 +0000 Subject: [PATCH] Add SSL certificate history tracking --- database_updates.php | 20 +++++++++++--- db.sql | 18 +++++++++++++ includes/database_version.php | 2 +- post/user/certificate.php | 35 ++++++++++++++++++++++++- scripts/cron_certificate_refresher.php | 36 +++++++++++++++++++++++++- 5 files changed, 105 insertions(+), 6 deletions(-) diff --git a/database_updates.php b/database_updates.php index 7883601f..fe623e24 100644 --- a/database_updates.php +++ b/database_updates.php @@ -2409,10 +2409,24 @@ if (LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION) { mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.6'"); } - // if (CURRENT_DATABASE_VERSION == '1.8.6') { - // // Insert queries here required to update to DB version 1.8.7 + if (CURRENT_DATABASE_VERSION == '1.8.6') { + mysqli_query($mysqli, " + CREATE TABLE `certificate_history` (`certificate_history_id` INT(11) NOT NULL AUTO_INCREMENT, + `certificate_history_column` VARCHAR(200) NOT NULL, + `certificate_history_old_value` TEXT NOT NULL, + `certificate_history_new_value` TEXT NOT NULL, + `certificate_history_certificate_id` INT(11) NOT NULL, + `certificate_history_modified_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`certificate_history_id`)) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci; + "); + + mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.7'"); + } + + // if (CURRENT_DATABASE_VERSION == '1.8.8') { + // // Insert queries here required to update to DB version 1.8.8 // // Then, update the database to the next sequential version - // mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.7'"); + // mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '1.8.8'"); // } } else { diff --git a/db.sql b/db.sql index 3431294a..a757b2a2 100644 --- a/db.sql +++ b/db.sql @@ -321,6 +321,24 @@ CREATE TABLE `categories` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `certificate_history` +-- + +DROP TABLE IF EXISTS `certificate_history`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `certificate_history` ( + `certificate_history_id` int(11) NOT NULL AUTO_INCREMENT, + `certificate_history_column` varchar(200) NOT NULL, + `certificate_history_old_value` text NOT NULL, + `certificate_history_new_value` text NOT NULL, + `certificate_history_certificate_id` int(11) NOT NULL, + `certificate_history_modified_at` datetime NOT NULL DEFAULT current_timestamp(), + PRIMARY KEY (`certificate_history_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `certificates` -- diff --git a/includes/database_version.php b/includes/database_version.php index dfc04fee..17de9b8e 100644 --- a/includes/database_version.php +++ b/includes/database_version.php @@ -5,4 +5,4 @@ * It is used in conjunction with database_updates.php */ -DEFINE("LATEST_DATABASE_VERSION", "1.8.6"); +DEFINE("LATEST_DATABASE_VERSION", "1.8.7"); diff --git a/post/user/certificate.php b/post/user/certificate.php index 2fe0a469..f2960904 100644 --- a/post/user/certificate.php +++ b/post/user/certificate.php @@ -64,8 +64,41 @@ if (isset($_POST['edit_certificate'])) { $expire = "'" . $expire . "'"; } + // Get current certificate info + $original_certificate_info = mysqli_fetch_assoc(mysqli_query($mysqli," + SELECT + certificates.*, + domains.domain_name + FROM certificates + LEFT JOIN domains ON certificate_domain_id = domain_id + WHERE certificate_id = $certificate_id + ")); + + // Update certificate mysqli_query($mysqli,"UPDATE certificates SET certificate_name = '$name', certificate_description = '$description', certificate_domain = '$domain', certificate_issued_by = '$issued_by', certificate_expire = $expire, certificate_public_key = '$public_key', certificate_notes = '$notes', certificate_domain_id = '$domain_id' WHERE certificate_id = $certificate_id"); + // Fetch the updated info + $new_certificate_info = mysqli_fetch_assoc(mysqli_query($mysqli," + SELECT + certificates.*, + domains.domain_name + FROM certificates + LEFT JOIN domains ON certificate_domain_id = domain_id + WHERE certificate_id = $certificate_id + ")); + + // Compare/log changes between old/new info + $ignored_columns = ["certificate_public_key", "certificate_updated_at", "certificate_accessed_at", "certificate_domain_id"]; + foreach ($original_certificate_info as $column => $old_value) { + $new_value = $new_certificate_info[$column]; + if ($old_value != $new_value && !in_array($column, $ignored_columns)) { + $column = sanitizeInput($column); + $old_value = sanitizeInput($old_value); + $new_value = sanitizeInput($new_value); + mysqli_query($mysqli,"INSERT INTO certificate_history SET certificate_history_column = '$column', certificate_history_old_value = '$old_value', certificate_history_new_value = '$new_value', certificate_history_certificate_id = $certificate_id"); + } + } + // Logging logAction("Certificate", "Edit", "$session_name edited certificate $name", $client_id, $certificate_id); @@ -144,7 +177,7 @@ if (isset($_POST['bulk_delete_certificates'])) { $client_id = intval($row['certificate_client_id']); mysqli_query($mysqli, "DELETE FROM certificates WHERE certificate_id = $certificate_id AND certificate_client_id = $client_id"); - + // Logging logAction("Certificate", "Delete", "$session_name deleted certificate $certificate_name", $client_id); diff --git a/scripts/cron_certificate_refresher.php b/scripts/cron_certificate_refresher.php index 865b0a3a..9cb2feb6 100644 --- a/scripts/cron_certificate_refresher.php +++ b/scripts/cron_certificate_refresher.php @@ -45,7 +45,7 @@ $sql_certificates = mysqli_query( while ($row = mysqli_fetch_array($sql_certificates)) { $certificate_id = intval($row['certificate_id']); $domain = sanitizeInput($row['certificate_domain']); - + $certificate = getSSL($domain); $expire = sanitizeInput($certificate['expire']); @@ -60,8 +60,42 @@ while ($row = mysqli_fetch_array($sql_certificates)) { echo "$public_key\n\n"; $expire = "'" . $expire . "'"; + + // Get current certificate info + $original_certificate_info = mysqli_fetch_assoc(mysqli_query($mysqli," + SELECT + certificates.*, + domains.domain_name + FROM certificates + LEFT JOIN domains ON certificate_domain_id = domain_id + WHERE certificate_id = $certificate_id + ")); + + // Update mysqli_query($mysqli,"UPDATE certificates SET certificate_issued_by = '$issued_by', certificate_expire = $expire, certificate_public_key = '$public_key' WHERE certificate_id = $certificate_id"); + // Fetch the updated info + $new_certificate_info = mysqli_fetch_assoc(mysqli_query($mysqli," + SELECT + certificates.*, + domains.domain_name + FROM certificates + LEFT JOIN domains ON certificate_domain_id = domain_id + WHERE certificate_id = $certificate_id + ")); + + // Compare/log changes between old/new info + $ignored_columns = ["certificate_public_key", "certificate_updated_at", "certificate_accessed_at", "certificate_domain_id"]; + foreach ($original_certificate_info as $column => $old_value) { + $new_value = $new_certificate_info[$column]; + if ($old_value != $new_value && !in_array($column, $ignored_columns)) { + $column = sanitizeInput($column); + $old_value = sanitizeInput($old_value); + $new_value = sanitizeInput($new_value); + mysqli_query($mysqli,"INSERT INTO certificate_history SET certificate_history_column = '$column', certificate_history_old_value = '$old_value', certificate_history_new_value = '$new_value', certificate_history_certificate_id = $certificate_id"); + } + } + } else { logApp("Cron-Certificate-Refresher", "error", "Cron Certificate Refresh - error updating Error updating $domain."); error_log("Certificate Cron Error - Error updating $domain");