static bool GeneratePolicyReleaseIDFromTree(char *release_id_out, size_t out_size, const char *policy_dir) { if (access(policy_dir, R_OK) != 0) { Log(LOG_LEVEL_ERR, "Cannot access policy directory '%s' to generate release ID", policy_dir); return false; } // fallback, produce some pseudo sha1 hash EVP_MD_CTX crypto_ctx; EVP_DigestInit(&crypto_ctx, EVP_get_digestbyname(HashNameFromId(GENERIC_AGENT_CHECKSUM_METHOD))); bool success = HashDirectoryTree(policy_dir, (const char *[]) { ".cf", ".dat", ".txt", ".conf", NULL},
/* * Key format: * * 7 bytes hash name, \0 padded at right * 1 byte \0 * N bytes filename */ static char *NewIndexKey(char type, const char *name, int *size) { char *chk_key; // Filename plus index_str in one block + \0 *size = strlen(name) + CF_INDEX_OFFSET + 1; chk_key = xcalloc(1, *size); // Data start after offset for index strncpy(chk_key, HashNameFromId(type), CF_INDEX_FIELD_LEN); strncpy(chk_key + CF_INDEX_OFFSET, name, strlen(name)); return chk_key; }
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; } }