diff --git a/src/modules/history_backend_mem.c b/src/modules/history_backend_mem.c index a9962d9f9..df895ab11 100644 --- a/src/modules/history_backend_mem.c +++ b/src/modules/history_backend_mem.c @@ -62,8 +62,6 @@ struct cfgstruct { char *directory; char *masterdb; /* Autogenerated for convenience, not a real config item */ char *db_secret; - char *prehash; - char *posthash; }; typedef struct HistoryLogObject HistoryLogObject; @@ -85,6 +83,8 @@ struct cfgstruct test; static char siphashkey_history_backend_mem[SIPHASH_KEY_LENGTH]; HistoryLogObject *history_hash_table[HISTORY_BACKEND_MEM_HASH_TABLE_SIZE]; static int already_loaded = 0; +static char *hbm_prehash = NULL; +static char *hbm_posthash = NULL; /* Forward declarations */ int hbm_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs); @@ -94,6 +94,7 @@ int hbm_rehash(void); int hbm_rehash_complete(void); static void setcfg(struct cfgstruct *cfg); static void freecfg(struct cfgstruct *cfg); +static void hbm_init_hashes(void); static void init_history_storage(ModuleInfo *modinfo); int hbm_modechar_del(Channel *channel, int modechar); int hbm_history_add(char *object, MessageTag *mtags, char *line); @@ -113,6 +114,7 @@ static void hbm_flush(void); MOD_TEST() { + hbm_init_hashes(); memset(&cfg, 0, sizeof(cfg)); memset(&test, 0, sizeof(test)); setcfg(&test); @@ -213,10 +215,23 @@ static void freecfg(struct cfgstruct *cfg) { safe_free(cfg->directory); safe_free(cfg->db_secret); - safe_free(cfg->prehash); - safe_free(cfg->posthash); } +static void hbm_init_hashes(void) +{ + char buf[256]; + + if (!hbm_prehash) + { + gen_random_alnum(buf, 128); + safe_strdup(hbm_prehash, buf); + } + if (!hbm_posthash) + { + gen_random_alnum(buf, 128); + safe_strdup(hbm_posthash, buf); + } +} /** Test the set::history::channel configuration */ int hbm_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs) @@ -719,11 +734,15 @@ int hbm_history_set_limit(char *object, int max_lines, long max_time) /** Read the master.db file, this is done at the INIT stage so we can still * reject the configuration / boot attempt. + * + * IMPORTANT: Because we run at INIT you must use test.xyz values and not cfg.xyz! */ static int hbm_read_masterdb(void) { UnrealDB *db; uint32_t mdb_version; + char *prehash = NULL; + char *posthash = NULL; db = unrealdb_open(test.masterdb, UNREALDB_MODE_READ, test.db_secret); @@ -732,7 +751,7 @@ static int hbm_read_masterdb(void) if (unrealdb_get_error_code() == UNREALDB_ERROR_FILENOTFOUND) { /* Database does not exist. Could be first boot */ - config_warn("[history] No database present at '%s', will start a new one", cfg.masterdb); + config_warn("[history] No database present at '%s', will start a new one", test.masterdb); // TODO: maybe check for condition where 'master.db' does not exist but // there are other .db files. if (!hbm_write_masterdb()) @@ -740,29 +759,42 @@ static int hbm_read_masterdb(void) return 1; } else { - config_warn("[history] Unable to open the database file '%s' for reading: %s", cfg.masterdb, unrealdb_get_error_string()); + config_warn("[history] Unable to open the database file '%s' for reading: %s", test.masterdb, unrealdb_get_error_string()); return 0; } } - safe_free(cfg.prehash); - safe_free(cfg.posthash); - /* Master db has an easy format: * 64 bits: version number * string: pre hash * string: post hash */ if (!unrealdb_read_int32(db, &mdb_version) || - !unrealdb_read_str(db, &cfg.prehash) || - !unrealdb_read_str(db, &cfg.posthash)) + !unrealdb_read_str(db, &prehash) || + !unrealdb_read_str(db, &posthash)) { + safe_free(prehash); + safe_free(posthash); config_error("[history] Read error from database file '%s': %s", - cfg.masterdb, unrealdb_get_error_string()); + test.masterdb, unrealdb_get_error_string()); unrealdb_close(db); return 0; } unrealdb_close(db); + + if (!prehash || !posthash) + { + config_error("[history] Read error from database file '%s': unexpected values encountered", + test.masterdb); + return 0; + } + + /* Now, safely switch over.. */ + safe_free(hbm_prehash); + safe_free(hbm_posthash); + hbm_prehash = prehash; + hbm_posthash = posthash; + return 1; } @@ -771,7 +803,6 @@ static int hbm_write_masterdb(void) { UnrealDB *db; uint32_t mdb_version; - char buf[512]; if (!test.db_secret) abort(); @@ -784,21 +815,13 @@ static int hbm_write_masterdb(void) return 0; } - if (!cfg.prehash) - { - gen_random_alnum(buf, 128); - safe_strdup(cfg.prehash, buf); - } - if (!cfg.posthash) - { - gen_random_alnum(buf, 128); - safe_strdup(cfg.posthash, buf); - } + if (!hbm_prehash || !hbm_posthash) + abort(); /* impossible */ mdb_version = 5000; if (!unrealdb_write_int32(db, mdb_version) || - !unrealdb_write_str(db, cfg.prehash) || - !unrealdb_write_str(db, cfg.posthash)) + !unrealdb_write_str(db, hbm_prehash) || + !unrealdb_write_str(db, hbm_posthash)) { config_error("[history] Unable to write to '%s': %s", test.masterdb, unrealdb_get_error_string()); @@ -955,7 +978,7 @@ static int hbm_read_db(char *fname) R_SAFE(unrealdb_read_str(db, &prehash)); R_SAFE(unrealdb_read_str(db, &posthash)); - if (!prehash || !posthash || strcmp(prehash, cfg.prehash) || strcmp(posthash, cfg.posthash)) + if (!prehash || !posthash || strcmp(prehash, hbm_prehash) || strcmp(posthash, hbm_posthash)) { config_warn("[history] Database '%s' does not belong to our 'master.db'. Are you mixing old with new .db files perhaps? This is not supported. File ignored.", fname); @@ -1084,11 +1107,11 @@ char *hbm_history_filename(HistoryLogObject *h) char hashdata[512]; char hash[128]; - if (!cfg.prehash || !cfg.posthash) + if (!hbm_prehash || !hbm_posthash) abort(); /* impossible */ strtolower_safe(oname, h->name, sizeof(oname)); - snprintf(hashdata, sizeof(hashdata), "%s %s %s", cfg.prehash, oname, cfg.posthash); + snprintf(hashdata, sizeof(hashdata), "%s %s %s", hbm_prehash, oname, hbm_posthash); sha256hash(hash, hashdata, strlen(hashdata)); snprintf(fname, sizeof(fname), "%s/%s.db", cfg.directory, hash); @@ -1142,8 +1165,8 @@ static int hbm_write_db(HistoryLogObject *h) W_SAFE(unrealdb_write_int32(db, HISTORYDB_MAGIC_FILE_START)); W_SAFE(unrealdb_write_int32(db, 5000)); /* VERSION */ - W_SAFE(unrealdb_write_str(db, cfg.prehash)); - W_SAFE(unrealdb_write_str(db, cfg.posthash)); + W_SAFE(unrealdb_write_str(db, hbm_prehash)); + W_SAFE(unrealdb_write_str(db, hbm_posthash)); W_SAFE(unrealdb_write_str(db, h->name)); W_SAFE(unrealdb_write_int64(db, h->max_lines)); @@ -1191,7 +1214,7 @@ static void hbm_delete_db(HistoryLogObject *h) { UnrealDB *db; char *fname; - if (!cfg.persist || !cfg.prehash || !cfg.posthash) + if (!cfg.persist || !hbm_prehash || !hbm_posthash) { #ifdef DEBUGMODE abort(); /* we should not be called, so debug this */