From f4798929e1332ddbd692e7d46f3ddf412e9870c1 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 15 Nov 2023 12:35:13 +0100 Subject: [PATCH 1/3] Only reload pihole.toml if the content changed Signed-off-by: DL6ER --- src/config/config.c | 20 ++++++++++++++++++++ src/config/toml_writer.c | 6 ++++++ src/files.c | 37 +++++++++++++++++++++++++++++++++++++ src/files.h | 3 +++ src/gc.c | 1 - 5 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/config/config.c b/src/config/config.c index b8eac3d3a..74c19608f 100644 --- a/src/config/config.c +++ b/src/config/config.c @@ -29,9 +29,12 @@ #include "api/api.h" // exit_code #include "signals.h" +// sha256sum() +#include "files.h" struct config config = { 0 }; static bool config_initialized = false; +uint8_t last_checksum[SHA256_DIGEST_SIZE] = { 0 }; // Private prototypes static bool port_in_use(const in_port_t port); @@ -1562,6 +1565,23 @@ void replace_config(struct config *newconf) void reread_config(void) { + + // Create checksum of config file + uint8_t checksum[SHA256_DIGEST_SIZE]; + if(!sha256sum(GLOBALTOMLPATH, checksum)) + { + log_err("Unable to create checksum of %s, not re-reading config file", GLOBALTOMLPATH); + return; + } + + // Compare checksums + if(memcmp(checksum, last_checksum, SHA256_DIGEST_SIZE) == 0) + { + log_debug(DEBUG_CONFIG, "Checksum of %s has not changed, not re-reading config file", GLOBALTOMLPATH); + return; + } + + log_info("Reloading config due to pihole.toml change"); struct config conf_copy; duplicate_config(&conf_copy, &config); diff --git a/src/config/toml_writer.c b/src/config/toml_writer.c index c756bc12b..f53959e50 100644 --- a/src/config/toml_writer.c +++ b/src/config/toml_writer.c @@ -22,6 +22,9 @@ // files_different() #include "files.h" +// defined in config/config.c +extern uint8_t last_checksum[SHA256_DIGEST_SIZE]; + static void migrate_config(void) { // Migrating dhcp.domain -> dns.domain @@ -176,5 +179,8 @@ bool writeFTLtoml(const bool verbose) log_debug(DEBUG_CONFIG, "pihole.toml unchanged"); } + if(!sha256sum(GLOBALTOMLPATH, last_checksum)) + log_err("Unable to create checksum of %s", GLOBALTOMLPATH); + return true; } diff --git a/src/files.c b/src/files.c index 525f57e3a..36455f40f 100644 --- a/src/files.c +++ b/src/files.c @@ -688,3 +688,40 @@ bool files_different(const char *pathA, const char* pathB, unsigned int from) return different; } + +// Create SHA256 checksum of a file +bool sha256sum(const char *path, uint8_t checksum[SHA256_DIGEST_SIZE]) +{ + // Open file + FILE *fp = fopen(path, "rb"); + if(fp == NULL) + { + log_warn("sha256_file(): Failed to open \"%s\" for reading: %s", path, strerror(errno)); + return false; + } + + // Initialize SHA2-256 context + struct sha256_ctx ctx; + sha256_init(&ctx); + + // Read file in chunks of bytes + const size_t pagesize = getpagesize(); + unsigned char *buf = calloc(pagesize, sizeof(char)); + size_t len; + while((len = fread(buf, sizeof(char), pagesize, fp)) > 0) + { + // Update SHA256 context + sha256_update(&ctx, len, buf); + } + + // Finalize SHA256 context + sha256_digest(&ctx, SHA256_DIGEST_SIZE, checksum); + + // Close file + fclose(fp); + + // Free memory + free(buf); + + return true; +} diff --git a/src/files.h b/src/files.h index 329ce876e..51770ef60 100644 --- a/src/files.h +++ b/src/files.h @@ -14,6 +14,8 @@ #include // setmntent() #include +// SHA256_DIGEST_SIZE +#include #define ZIP_ROTATIONS 3 #define MAX_ROTATIONS 15 @@ -31,6 +33,7 @@ struct mntent *get_filesystem_details(const char *path); bool directory_exists(const char *path); void rotate_files(const char *path, char **first_file); bool files_different(const char *pathA, const char* pathB, unsigned int from); +bool sha256sum(const char *path, uint8_t checksum[SHA256_DIGEST_SIZE]); int parse_line(char *line, char **key, char **value); diff --git a/src/gc.c b/src/gc.c index 322a92ab0..ad793413d 100644 --- a/src/gc.c +++ b/src/gc.c @@ -374,7 +374,6 @@ void *GC_thread(void *val) if(check_inotify_event()) { // Reload config - log_info("Reloading config due to pihole.toml change"); reread_config(); } From adf8a13e9d8302db23998d4970c60d47aa67d7bb Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 15 Nov 2023 14:20:59 +0100 Subject: [PATCH 2/3] Add pihole-FTL sha256sum Signed-off-by: DL6ER --- src/args.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/args.c b/src/args.c index 57550e52c..381b7f3bc 100644 --- a/src/args.c +++ b/src/args.c @@ -62,6 +62,8 @@ #include "config/password.h" // idn2_to_ascii_lz() #include +// sha256sum() +#include "files.h" // defined in dnsmasq.c extern void print_dnsmasq_version(const char *yellow, const char *green, const char *bold, const char *normal); @@ -476,6 +478,24 @@ void parse_args(int argc, char* argv[]) } } + // sha256sum mode + if(argc == 3 && strcmp(argv[1], "sha256sum") == 0) + { + // Enable stdout printing + cli_mode = true; + uint8_t checksum[SHA256_DIGEST_SIZE]; + if(!sha256sum(argv[2], checksum)) + exit(EXIT_FAILURE); + + // Convert checksum to hex string + char hex[SHA256_DIGEST_SIZE*2+1]; + sha256_raw_to_hex(checksum, hex); + + // Print result + printf("%s %s\n", hex, argv[2]); + exit(EXIT_SUCCESS); + } + // start from 1, as argv[0] is the executable name for(int i = 1; i < argc; i++) { @@ -934,6 +954,7 @@ void parse_args(int argc, char* argv[]) printf(" Decoding: %spihole-FTL idn2 -d %spunycode%s\n\n", green, cyan, normal); printf("%sOther:%s\n", yellow, normal); + printf("\t%ssha256sum %sfile%s Calculate SHA256 checksum of a file\n", green, cyan, normal); printf("\t%sdhcp-discover%s Discover DHCP servers in the local\n", green, normal); printf("\t network\n"); printf("\t%sarp-scan %s[-a/-x]%s Use ARP to scan local network for\n", green, cyan, normal); From ea7753d3ec60905921ec12a20f14fac673a3303f Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 15 Nov 2023 14:27:53 +0100 Subject: [PATCH 3/3] Add SHA256 CI test Signed-off-by: DL6ER --- test/test_suite.bats | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/test_suite.bats b/test/test_suite.bats index aca80a551..d8d5cbaca 100644 --- a/test/test_suite.bats +++ b/test/test_suite.bats @@ -1524,6 +1524,12 @@ [[ $status == 0 ]] } +@test "SHA256 checksum working" { + run bash -c './pihole-FTL sha256sum test/test.pem' + printf "%s\n" "${lines[@]}" + [[ ${lines[0]} == "eae293f0c30369935a7457a789658bedebf92d544e7526bc43aa07883a597fa9 test/test.pem" ]] +} + @test "API validation" { run python3 test/api/checkAPI.py printf "%s\n" "${lines[@]}" @@ -1575,7 +1581,7 @@ [[ ${lines[0]} == "3" ]] run bash -c 'grep -c "DEBUG_CONFIG: pihole.toml unchanged" /var/log/pihole/FTL.log' printf "%s\n" "${lines[@]}" - [[ ${lines[0]} == "4" ]] + [[ ${lines[0]} == "3" ]] run bash -c 'grep -c "DEBUG_CONFIG: Config file written to /etc/pihole/dnsmasq.conf" /var/log/pihole/FTL.log' printf "%s\n" "${lines[@]}" [[ ${lines[0]} == "1" ]] @@ -1587,5 +1593,5 @@ [[ ${lines[0]} == "1" ]] run bash -c 'grep -c "DEBUG_CONFIG: custom.list unchanged" /var/log/pihole/FTL.log' printf "%s\n" "${lines[@]}" - [[ ${lines[0]} == "4" ]] + [[ ${lines[0]} == "3" ]] }