int FileHashChanged(char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], int warnlevel, enum cfhashes type, Attributes attr, Promise *pp) /* Returns false if filename never seen before, and adds a checksum to the database. Returns true if hashes do not match and also potentially updates database to the new value */ { int i, size = 21; unsigned char dbdigest[EVP_MAX_MD_SIZE + 1]; CF_DB *dbp; CfDebug("HashChanged: key %s (type=%d) with data %s\n", filename, type, HashPrint(type, digest)); size = FileHashSize(type); if (!OpenDB(&dbp, dbid_checksums)) { cfPS(OUTPUT_LEVEL_ERROR, CF_FAIL, "", pp, attr, "Unable to open the hash database!"); return false; } if (ReadHash(dbp, type, filename, dbdigest)) { for (i = 0; i < size; i++) { if (digest[i] != dbdigest[i]) { CfDebug("Found cryptohash for %s in database but it didn't match\n", filename); CfOut(warnlevel, "", "ALERT: Hash (%s) for %s changed!", FileHashName(type), filename); if (pp->ref) { CfOut(warnlevel, "", "Preceding promise: %s", pp->ref); } if (attr.change.update) { cfPS(warnlevel, CF_CHG, "", pp, attr, " -> Updating hash for %s to %s", filename, HashPrint(type, digest)); DeleteHash(dbp, type, filename); WriteHash(dbp, type, filename, digest); } else { cfPS(warnlevel, CF_FAIL, "", pp, attr, "!! Hash for file \"%s\" changed", filename); } CloseDB(dbp); return true; } } cfPS(OUTPUT_LEVEL_VERBOSE, CF_NOP, "", pp, attr, " -> File hash for %s is correct", filename); CloseDB(dbp); return false; } else { /* Key was not found, so install it */ cfPS(warnlevel, CF_CHG, "", pp, attr, " !! File %s was not in %s database - new file found", filename, FileHashName(type)); CfDebug("Storing checksum for %s in database %s\n", filename, HashPrint(type, digest)); WriteHash(dbp, type, filename, digest); LogHashChange(filename, cf_file_new, "New file found", pp); CloseDB(dbp); return false; } }
void PurgeHashes(char *path, Attributes attr, Promise *pp) /* Go through the database and purge records about non-existent files */ { CF_DB *dbp; CF_DBC *dbcp; struct stat statbuf; int ksize, vsize; char *key; void *value; if (!OpenDB(&dbp,dbid_checksums)) { return; } if (path) { if (cfstat(path, &statbuf) == -1) { DeleteDB(dbp, path); } CloseDB(dbp); return; } /* Acquire a cursor for the database. */ if (!NewDBCursor(dbp, &dbcp)) { CfOut(OUTPUT_LEVEL_INFORM, "", " !! Unable to scan hash database"); CloseDB(dbp); return; } /* Walk through the database and print out the key/data pairs. */ while (NextDB(dbp, dbcp, &key, &ksize, &value, &vsize)) { char *obj = (char *) key + CF_INDEX_OFFSET; if (cfstat(obj, &statbuf) == -1) { if (attr.change.update) { DBCursorDeleteEntry(dbcp); } else { cfPS(OUTPUT_LEVEL_ERROR, CF_WARN, "", pp, attr, "ALERT: File %s no longer exists!", obj); } LogHashChange(obj, cf_file_removed, "File removed", pp); } memset(&key, 0, sizeof(key)); memset(&value, 0, sizeof(value)); } DeleteDBCursor(dbp, dbcp); CloseDB(dbp); }
int FileHashChanged(EvalContext *ctx, char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type, Attributes attr, Promise *pp) { int i, size = 21; unsigned char dbdigest[EVP_MAX_MD_SIZE + 1]; CF_DB *dbp; char buffer[EVP_MAX_MD_SIZE * 4]; CfDebug("HashChanged: key %s (type=%d) with data %s\n", filename, type, HashPrintSafe(type, digest, buffer)); size = FileHashSize(type); if (!OpenDB(&dbp, dbid_checksums)) { cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_FAIL, "", pp, attr, "Unable to open the hash database!"); return false; } if (ReadHash(dbp, type, filename, dbdigest)) { for (i = 0; i < size; i++) { if (digest[i] != dbdigest[i]) { CfDebug("Found cryptohash for %s in database but it didn't match\n", filename); CfOut(OUTPUT_LEVEL_ERROR, "", "ALERT: Hash (%s) for %s changed!", FileHashName(type), filename); if (pp->comment) { CfOut(OUTPUT_LEVEL_ERROR, "", "Preceding promise: %s", pp->comment); } if (attr.change.update) { cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_CHANGE, "", pp, attr, " -> Updating hash for %s to %s", filename, HashPrintSafe(type, digest, buffer)); DeleteHash(dbp, type, filename); WriteHash(dbp, type, filename, digest); } else { cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_FAIL, "", pp, attr, "!! Hash for file \"%s\" changed", filename); } CloseDB(dbp); return true; } } cfPS(ctx, OUTPUT_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, "", pp, attr, " -> File hash for %s is correct", filename); CloseDB(dbp); return false; } else { /* Key was not found, so install it */ cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_CHANGE, "", pp, attr, " !! File %s was not in %s database - new file found", filename, FileHashName(type)); CfDebug("Storing checksum for %s in database %s\n", filename, HashPrintSafe(type, digest, buffer)); WriteHash(dbp, type, filename, digest); LogHashChange(filename, FILE_STATE_NEW, "New file found", pp); CloseDB(dbp); return false; } }
PromiseResult PurgeHashes(EvalContext *ctx, char *path, Attributes attr, const Promise *pp) /* Go through the database and purge records about non-existent files */ { CF_DB *dbp; CF_DBC *dbcp; struct stat statbuf; int ksize, vsize; char *key; void *value; if (!OpenDB(&dbp,dbid_checksums)) { return PROMISE_RESULT_NOOP; } if (path) { if (stat(path, &statbuf) == -1) { DeleteDB(dbp, path); } CloseDB(dbp); return PROMISE_RESULT_NOOP; } /* Acquire a cursor for the database. */ if (!NewDBCursor(dbp, &dbcp)) { Log(LOG_LEVEL_INFO, "Unable to scan hash database"); CloseDB(dbp); return PROMISE_RESULT_NOOP; } /* Walk through the database and print out the key/data pairs. */ PromiseResult result = PROMISE_RESULT_NOOP; while (NextDB(dbcp, &key, &ksize, &value, &vsize)) { char *obj = (char *) key + CF_INDEX_OFFSET; if (stat(obj, &statbuf) == -1) { if (attr.change.update) { DBCursorDeleteEntry(dbcp); } else { cfPS(ctx, LOG_LEVEL_NOTICE, PROMISE_RESULT_WARN, pp, attr, "File '%s' no longer exists", obj); result = PromiseResultUpdate(result, PROMISE_RESULT_WARN); } LogHashChange(obj, FILE_STATE_REMOVED, "File removed", pp); } } DeleteDBCursor(dbcp); CloseDB(dbp); return result; }
int FileHashChanged(EvalContext *ctx, const char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type, Attributes attr, const Promise *pp, PromiseResult *result) { int size; unsigned char dbdigest[EVP_MAX_MD_SIZE + 1]; CF_DB *dbp; char buffer[EVP_MAX_MD_SIZE * 4]; size = HashSizeFromId(type); if (!OpenDB(&dbp, dbid_checksums)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, attr, "Unable to open the hash database!"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if (ReadHash(dbp, type, filename, dbdigest)) { if (memcmp(digest, dbdigest, size) != 0) { Log(LOG_LEVEL_NOTICE, "Hash '%s' for '%s' changed!", HashNameFromId(type), filename); if (pp->comment) { Log(LOG_LEVEL_NOTICE, "Preceding promise '%s'", pp->comment); } if (attr.change.update) { cfPS(ctx, LOG_LEVEL_NOTICE, PROMISE_RESULT_CHANGE, pp, attr, "Updating hash for '%s' to '%s'", filename, HashPrintSafe(type, true, digest, buffer)); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); DeleteHash(dbp, type, filename); WriteHash(dbp, type, filename, digest); } else { cfPS(ctx, LOG_LEVEL_NOTICE, PROMISE_RESULT_FAIL, pp, attr, "Hash for file '%s' changed", filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } CloseDB(dbp); return true; } cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, attr, "File hash for %s is correct", filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_NOOP); CloseDB(dbp); return false; } else { /* Key was not found, so install it */ cfPS(ctx, LOG_LEVEL_NOTICE, PROMISE_RESULT_CHANGE, pp, attr, "File '%s' was not in '%s' database - new file found", filename, HashNameFromId(type)); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); Log(LOG_LEVEL_DEBUG, "Storing checksum for '%s' in database '%s'", filename, HashPrintSafe(type, true, digest, buffer)); WriteHash(dbp, type, filename, digest); LogHashChange(filename, FILE_STATE_NEW, "New file found", pp); CloseDB(dbp); return false; } }
int FileHashChanged(EvalContext *ctx, char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type, Attributes attr, Promise *pp) { int i, size = 21; unsigned char dbdigest[EVP_MAX_MD_SIZE + 1]; CF_DB *dbp; char buffer[EVP_MAX_MD_SIZE * 4]; size = FileHashSize(type); if (!OpenDB(&dbp, dbid_checksums)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, attr, "Unable to open the hash database!"); return false; } if (ReadHash(dbp, type, filename, dbdigest)) { for (i = 0; i < size; i++) { if (digest[i] != dbdigest[i]) { Log(LOG_LEVEL_ERR, "Hash '%s' for '%s' changed!", FileHashName(type), filename); if (pp->comment) { Log(LOG_LEVEL_ERR, "Preceding promise: %s", pp->comment); } if (attr.change.update) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_CHANGE, pp, attr, "Updating hash for %s to %s", filename, HashPrintSafe(type, digest, buffer)); DeleteHash(dbp, type, filename); WriteHash(dbp, type, filename, digest); } else { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, attr, "!! Hash for file \"%s\" changed", filename); } CloseDB(dbp); return true; } } cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, attr, "File hash for %s is correct", filename); CloseDB(dbp); return false; } else { /* Key was not found, so install it */ cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_CHANGE, pp, attr, "File '%s' was not in '%s' database - new file found", filename, FileHashName(type)); Log(LOG_LEVEL_DEBUG, "Storing checksum for '%s' in database '%s'", filename, HashPrintSafe(type, digest, buffer)); WriteHash(dbp, type, filename, digest); LogHashChange(filename, FILE_STATE_NEW, "New file found", pp); CloseDB(dbp); return false; } }