Skip to content

Commit

Permalink
Merge pull request #1778 from pi-hole/new/config_checksum
Browse files Browse the repository at this point in the history
Only reload pihole.toml if changed
  • Loading branch information
DL6ER authored Nov 26, 2023
2 parents 8bba6fa + a7dbcc6 commit 30c3e9c
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 3 deletions.
21 changes: 21 additions & 0 deletions src/args.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
#include "config/password.h"
// idn2_to_ascii_lz()
#include <idn2.h>
// 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);
Expand Down Expand Up @@ -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++)
{
Expand Down Expand Up @@ -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);
Expand Down
20 changes: 20 additions & 0 deletions src/config/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -1571,6 +1574,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);

Expand Down
6 changes: 6 additions & 0 deletions src/config/toml_writer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
37 changes: 37 additions & 0 deletions src/files.c
Original file line number Diff line number Diff line change
Expand Up @@ -641,3 +641,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 <pagesize> 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;
}
3 changes: 3 additions & 0 deletions src/files.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include <sys/stat.h>
// setmntent()
#include <mntent.h>
// SHA256_DIGEST_SIZE
#include <nettle/sha2.h>

#define MAX_ROTATIONS 15
#define BACKUP_DIR "/etc/pihole/config_backups"
Expand All @@ -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);

Expand Down
1 change: 0 additions & 1 deletion src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
10 changes: 8 additions & 2 deletions test/test_suite.bats
Original file line number Diff line number Diff line change
Expand Up @@ -1520,6 +1520,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[@]}"
Expand Down Expand Up @@ -1571,7 +1577,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" ]]
Expand All @@ -1583,5 +1589,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" ]]
}

0 comments on commit 30c3e9c

Please sign in to comment.