From: Alberto Leiva Popper Date: Tue, 12 Dec 2023 21:16:39 +0000 (-0600) Subject: Create CACHEDIR.TAG during cache initialization X-Git-Tag: 1.6.1~5 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=5a3cb687afe086dd3cf07cc7bbf36d8713c98707;p=thirdparty%2FFORT-validator.git Create CACHEDIR.TAG during cache initialization To hint backup software not to copy the cache. https://bford.info/cachedir/ Fixes #104. --- diff --git a/src/Makefile.am b/src/Makefile.am index 9aa7d768..25ee95af 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -45,7 +45,6 @@ fort_SOURCES += types/uri.h types/uri.c fort_SOURCES += types/vrp.c types/vrp.h fort_SOURCES += cache/local_cache.c cache/local_cache.h -fort_SOURCES += cache/tmp.c cache/tmp.h fort_SOURCES += config/boolean.c config/boolean.h fort_SOURCES += config/filename_format.h config/filename_format.c diff --git a/src/cache/local_cache.c b/src/cache/local_cache.c index ae1e9d1d..38b46cdf 100644 --- a/src/cache/local_cache.c +++ b/src/cache/local_cache.c @@ -1,6 +1,7 @@ #include "cache/local_cache.h" #include +#include #include #include "alloc.h" @@ -44,6 +45,9 @@ struct rpki_cache { #define CACHE_METAFILE "cache.json" #define TAGNAME_VERSION "fort-version" +#define CACHEDIR_TAG "CACHEDIR.TAG" +#define TMPDIR "tmp" + #define TAL_METAFILE "tal.json" #define TAGNAME_URL "url" #define TAGNAME_ATTEMPT_TS "attempt-timestamp" @@ -51,24 +55,55 @@ struct rpki_cache { #define TAGNAME_SUCCESS_TS "success-timestamp" #define TAGNAME_IS_NOTIF "is-rrdp-notification" +static atomic_uint file_counter; + static char * -get_cache_metafile_name(void) +get_cache_filename(char const *name, bool fatal) { struct path_builder pb; int error; - error = pb_init_cache(&pb, NULL, CACHE_METAFILE); + error = pb_init_cache(&pb, NULL, name); if (error) { - pr_op_err("Cannot create path to " CACHE_METAFILE ": %s", - strerror(error)); - return NULL; + if (fatal) { + pr_crit("Cannot create path to %s: %s", name, + strerror(error)); + } else { + pr_op_err("Cannot create path to %s: %s", name, + strerror(error)); + return NULL; + } } return pb.string; } -void -cache_setup(void) +static int +write_simple_file(char const *filename, char const *content) +{ + FILE *file; + int error; + + file = fopen(filename, "w"); + if (file == NULL) + goto fail; + + if (fprintf(file, "%s", content) < 0) + goto fail; + + fclose(file); + return 0; + +fail: + error = errno; + pr_op_err("Cannot write %s: %s", filename, strerror(error)); + if (file != NULL) + fclose(file); + return error; +} + +static void +init_cache_metafile(void) { char *filename; json_t *root; @@ -76,10 +111,7 @@ cache_setup(void) char const *file_version; int error; - filename = get_cache_metafile_name(); - if (filename == NULL) - return; - + filename = get_cache_filename(CACHE_METAFILE, true); root = json_load_file(filename, 0, &jerror); if (root == NULL) { @@ -114,41 +146,93 @@ end: json_decref(root); free(filename); } +static void +init_cachedir_tag(void) +{ + char *filename; + + filename = get_cache_filename(CACHEDIR_TAG, false); + if (filename == NULL) + return; + + if (file_exists(filename) == ENOENT) + write_simple_file(filename, + "Signature: 8a477f597d28d172789f06886806bc55\n" + "# This file is a cache directory tag created by Fort.\n" + "# For information about cache directory tags, see:\n" + "# https://bford.info/cachedir/\n"); + + free(filename); +} + +static void +init_tmp_dir(void) +{ + char *dirname; + int error; + + dirname = get_cache_filename(TMPDIR, true); + + error = mkdir_p(dirname, true); + if (error) + pr_crit("Cannot create %s: %s", dirname, strerror(error)); + + free(dirname); +} + void -cache_teardown(void) +cache_setup(void) { - static char const * const CONTENT = "{ \"" TAGNAME_VERSION "\": \"" - PACKAGE_VERSION "\" }\n"; + init_cache_metafile(); + init_cachedir_tag(); + init_tmp_dir(); +} +void +cache_teardown(void) +{ char *filename; - FILE *file = NULL; - int error; - filename = get_cache_metafile_name(); + filename = get_cache_filename(CACHE_METAFILE, false); if (filename == NULL) return; - file = fopen(filename, "w"); - if (file == NULL) - goto fail; + write_simple_file(filename, "{ \"" TAGNAME_VERSION "\": \"" + PACKAGE_VERSION "\" }\n"); + free(filename); +} - if (fprintf(file, CONTENT) < 0) - goto fail; +/* + * Returns a unique temporary file name in the local cache. + * + * The file will not be automatically deleted when it is closed or the program + * terminates. + * + * The name of the function is inherited from tmpfile(3). + * + * The resulting string needs to be released. + */ +int +cache_tmpfile(char **filename) +{ + struct path_builder pb; + int error; - free(filename); - fclose(file); - return; + error = pb_init_cache(&pb, NULL, TMPDIR); + if (error) + return error; + error = pb_append_u32(&pb, atomic_fetch_add(&file_counter, 1u)); + if (error) { + pb_cleanup(&pb); + return error; + } -fail: - error = errno; - pr_op_err("Cannot write %s: %s", filename, strerror(error)); - free(filename); - if (file != NULL) - fclose(file); + *filename = pb.string; + return 0; } static char * -get_json_filename(struct rpki_cache *cache) +get_tal_json_filename(struct rpki_cache *cache) { struct path_builder pb; return pb_init_cache(&pb, cache->tal, TAL_METAFILE) @@ -248,7 +332,7 @@ load_tal_json(struct rpki_cache *cache) * without killing itself. It's just a cache of a cache. */ - filename = get_json_filename(cache); + filename = get_tal_json_filename(cache); if (filename == NULL) return; @@ -357,7 +441,7 @@ write_tal_json(struct rpki_cache *cache) if (json == NULL) return; - filename = get_json_filename(cache); + filename = get_tal_json_filename(cache); if (filename == NULL) goto end; diff --git a/src/cache/local_cache.h b/src/cache/local_cache.h index d01932a5..93eb11f1 100644 --- a/src/cache/local_cache.h +++ b/src/cache/local_cache.h @@ -8,6 +8,8 @@ struct rpki_cache; void cache_setup(void); void cache_teardown(void); +int cache_tmpfile(char **); + struct rpki_cache *cache_create(char const *); /* Will destroy the cache object, but not the cache directory itself, obv. */ void cache_destroy(struct rpki_cache *); diff --git a/src/cache/tmp.c b/src/cache/tmp.c deleted file mode 100644 index 6d969d5f..00000000 --- a/src/cache/tmp.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "cache/tmp.h" - -#include - -#include "common.h" -#include "data_structure/path_builder.h" - -static atomic_uint file_counter; - -static int -pb_init_tmp(struct path_builder *pb) -{ - return pb_init_cache(pb, NULL, "tmp"); -} - -int -init_tmpdir(void) -{ - struct path_builder pb; - int error; - - error = pb_init_tmp(&pb); - if (error) - return error; - - error = mkdir_p(pb.string, true); - - pb_cleanup(&pb); - return error; -} - -/* - * Returns a unique temporary file name in the local cache. - * - * The file will not be automatically deleted when it is closed or the program - * terminates. - * - * The name of the function is inherited from tmpfile(3). - * - * The resulting string needs to be released. - */ -int -cache_tmpfile(char **filename) -{ - struct path_builder pb; - int error; - - error = pb_init_tmp(&pb); - if (error) - return error; - error = pb_append_u32(&pb, atomic_fetch_add(&file_counter, 1u)); - if (error) - return error; - - *filename = pb.string; - return 0; -} diff --git a/src/cache/tmp.h b/src/cache/tmp.h deleted file mode 100644 index 9d30a229..00000000 --- a/src/cache/tmp.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef SRC_CACHE_TMP_H_ -#define SRC_CACHE_TMP_H_ - -int init_tmpdir(void); -int cache_tmpfile(char **filename); - -#endif /* SRC_CACHE_TMP_H_ */ diff --git a/src/http/http.c b/src/http/http.c index 7b356be9..27a10b9a 100644 --- a/src/http/http.c +++ b/src/http/http.c @@ -7,8 +7,8 @@ #include "config.h" #include "file.h" #include "log.h" -#include "cache/tmp.h" #include "data_structure/uthash.h" +#include "cache/local_cache.h" struct http_handler { CURL *curl; diff --git a/src/object/tal.c b/src/object/tal.c index 0f5ad1e9..ebc588f4 100644 --- a/src/object/tal.c +++ b/src/object/tal.c @@ -14,7 +14,6 @@ #include "state.h" #include "thread_var.h" #include "validation_handler.h" -#include "cache/tmp.h" #include "crypto/base64.h" #include "object/certificate.h" #include "rtr/db/vrps.h" @@ -505,17 +504,11 @@ perform_standalone_validation(void) struct threads_list threads = SLIST_HEAD_INITIALIZER(threads); struct validation_thread *thread; struct db_table *db = NULL; - int error, tmperr; + int error = 0; + int tmperr; cache_setup(); - error = init_tmpdir(); - if (error) { - pr_val_err("Cannot initialize the cache's temporal directory: %s", - strerror(error)); - return NULL; - } - /* TODO (fine) Maybe don't spawn threads if there's only one TAL */ if (foreach_file(config_get_tal(), ".tal", true, spawn_tal_thread, &threads) != 0) {